我的配置文件已经配置好了事务管理,我也测试过,一旦中间出错,事务确实会回滚,不会修改数据。
可是我用两个线程分别调用这个事务100次来插入数据,却没有200条,因为中间有些数据是重复了。
对于同一个事务的两百次执行,不是按顺序执行吗,显然就是两个线程穿插执行影响到了彼此。
因为正在学习当中,所以有些迷惑。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-mybatis.xml")
public class TestSellingOrderDao {
@Autowired
private ISellingOrderService sellingOrderService;
@Autowired
private IDealedBookDao dealedBookDao;
@Test
public void sellDaoShouldNotBeNull() {
assertNotNull(sellingOrderDao);
DealedBook dealedBook = new DealedBook();
dealedBook.setBookId(1);
dealedBook.setDealedNum("DealedNum");
dealedBook.setSellingPrice(6);
dealedBook.setRentalPrice(12);
dealedBook.setDistrictId(1);
dealedBook.setUserId(1);
dealedBook.setDatetime(new Date());
for (int i = 1; i <= 1000; i++)
dealedBookDao.insert(dealedBook);
SellingOrder order = new SellingOrder();
order.setUserId(2);
order.setDeliveryMethodId(1); //
order.setBookId(dealedBook.getBookId()); //
order.setAmount(5);
order.setDatetime(new Date());
order.setPayed(1);
// 取书号:学校编号+日期+待售书的ID
order.setTakingBookNum( "" +
"SYSU" +
new SimpleDateFormat("yyyyMMdd").format(new Date()) +
String.format("%05d", dealedBook.getId())
);
new Thread() {
@Override
public void run() {
for (int i = 1; i <= 100; i++)
sellingOrderService.insertOrder(order); // 执行事务
}
}.start();
for (int i = 1; i <= 100; i++)
sellingOrderService.insertOrder(order); // 执行事务
}
}
package com.databasegroup.service.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.databasegroup.dao.IDealedBookDao;
import com.databasegroup.dao.ISellingOrderDao;
import com.databasegroup.exception.NoEnoughBooksException;
import com.databasegroup.model.DealedBook;
import com.databasegroup.model.SellingOrder;
import com.databasegroup.service.ISellingOrderService;
@Service("sellingOrderService")
public class SellingOrderServiceImpl implements ISellingOrderService {
@Resource
private ISellingOrderDao sellingOrderDao;
@Resource
private IDealedBookDao dealedBookDao;
@Override
public void insertOrder(SellingOrder sellingOrder) {
StringBuilder dealedBookId = new StringBuilder();
int bookId = sellingOrder.getBookId();
int amount = sellingOrder.getAmount();
List<DealedBook> dealedBooks =
dealedBookDao.getNoDealedBookByBookIdAndAmount(bookId, amount);
if (dealedBooks.size() != amount)
{
throw new NoEnoughBooksException("没有足够的书本"); // 错误抛出后,事务会回滚
}
for (DealedBook dealedBook : dealedBooks) {
dealedBook.setSelled(1);
dealedBook.setSelledDatetime(new Date());
dealedBookId.append("" + dealedBook.getId() + '|');
dealedBookDao.update(dealedBook); // 修改另外表的数据
}
if (dealedBookId.length() > 0)
dealedBookId = dealedBookId.deleteCharAt(dealedBookId.length()-1);
// 设置dealed_book_id字段的值
sellingOrder.setDealedBookIds(dealedBookId.toString());
sellingOrderDao.insert(sellingOrder); /
}
}
spring-mybatis.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<!-- com.databasegroup下的组件(bean),并排除controller -->
<context:component-scan base-package="com.databasegroup">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<mvc:annotation-driven />
<!-- mybatis 配置1:读参数 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties" />
</bean>
<!-- mybatis 配置2:数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="${jdbc.initialSize}"></property>
<!-- 连接池最大数量 -->
<property name="maxActive" value="${jdbc.maxActive}"></property>
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="${jdbc.maxIdle}"></property>
<!-- 连接池最小空闲 -->
<property name="minIdle" value="${jdbc.minIdle}"></property>
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="${jdbc.maxWait}"></property>
</bean>
<!-- spring和MyBatis整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自动扫描映射文件 -->
<property name="mapperLocations" value="classpath:/mapper/*.xml"></property>
<!-- mybatis配置 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 使用别名 -->
<property name="typeAliasesPackage" value="com.databasegroup.model"></property>
</bean>
<!-- DAO接口所在包名,Spring会自动查找其下的类 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.databasegroup.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- spring declarative transaction management -->
<aop:config>
<aop:pointcut id="allServiceMethods"
expression="execution(* com.databasegroup.service.impl.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="allServiceMethods" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="reduce*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
</beans>
servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<!-- 扫描com.databasegroup.fortest.controller下的controller -->
<context:component-scan base-package="com.databasegroup.controller">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 注解驱动 -->
<mvc:annotation-driven />
<!-- 处理静态资源的请求 -->
<mvc:resources location="/WEB-INF/views/css/" mapping="/css/**" />
<mvc:resources location="/WEB-INF/views/js/" mapping="/js/**" />
<mvc:resources location="/images/" mapping="/images/**" />
<mvc:resources location="/WEB-INF/views/admin/" mapping="/admin/**" />
<!-- 不懂标记 -->
<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<!-- 不懂标记 -->
<bean
class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
<!-- 定义跳转的文件的前后缀 ,视图模式配置 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 上传文件 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8" />
<!-- 最大内存大小 -->
<property name="maxInMemorySize" value="10240" />
<!-- 最大文件大小,-1为不限制大小 -->
<property name="maxUploadSize" value="-1" />
</bean>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/center"/>
<mvc:mapping path="/books"/>
<mvc:mapping path="/alipay/**"/>
<mvc:mapping path="/buy_rent"/>
<mvc:mapping path="/pay/**"/>
<mvc:mapping path="/rent/**"/>
<mvc:mapping path="/success/**"/>
<bean class="com.databasegroup.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/backend/**"/>
<bean class="com.databasegroup.interceptor.AdminLoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>
3 个解决方案
#1
原因我懂了,因为事务之间是并发运行的,所以当然有问题。
那我就用synchronized关键来同步方法insertOrder,那么基本上每次调用service的insertOrder,应该都是按顺序来执行吧。
可是我测试了下,加上synchronized关键字,还是结果还是错的
那我就用synchronized关键来同步方法insertOrder,那么基本上每次调用service的insertOrder,应该都是按顺序来执行吧。
可是我测试了下,加上synchronized关键字,还是结果还是错的
@Override
public synchronized void insertOrder(SellingOrder sellingOrder) {
StringBuilder dealedBookId = new StringBuilder();
int bookId = sellingOrder.getBookId();
int amount = sellingOrder.getAmount();
List<DealedBook> dealedBooks =
dealedBookDao.getNoDealedBookByBookIdAndAmount(bookId, amount);
if (dealedBooks.size() != amount)
{
throw new NoEnoughBooksException("没有足够的书本"); // 错误抛出后,事务会回滚
}
for (DealedBook dealedBook : dealedBooks) {
dealedBook.setSelled(1);
dealedBook.setSelledDatetime(new Date());
dealedBookId.append("" + dealedBook.getId() + '|');
dealedBookDao.update(dealedBook); // 修改另外表的数据
}
if (dealedBookId.length() > 0)
dealedBookId = dealedBookId.deleteCharAt(dealedBookId.length()-1);
// 设置dealed_book_id字段的值
sellingOrder.setDealedBookIds(dealedBookId.toString());
sellingOrderDao.insert(sellingOrder); /
}
#2
spring里面的bean默认都是单例的,那么我上面的service实例自然都是同一个对象,我也输出查看过,确实是。
那么为什么加了synchronized,却不是按顺序执行
那么为什么加了synchronized,却不是按顺序执行
#3
下面是我测试出来的结果,我把两个线程分别设置了运行50次,实际上却会有线程少运行,不知道为什么。
加起来起码要100次,还有就是
Thread-2: 2 6|7|8|9|10
main: 3 6|7|8|9|10
这两行右边是插入的数据,实际上应该是要不同才对。我还没找到原因,难道是因为上一个事务(方法)还没来得及提交,下一个事务(方法)就开始执行了,所以就从数据找到了尚未修改的数据?可是这是为什么呢
main: 1 1|2|3|4|5
Thread-2: 2 6|7|8|9|10
main: 3 6|7|8|9|10
Thread-2: 4 11|12|13|14|15
main: 5 11|12|13|14|15
main: 6 16|17|18|19|20
Thread-2: 7 21|22|23|24|25
main: 8 26|27|28|29|30
main: 9 31|32|33|34|35
main: 10 36|37|38|39|40
main: 11 41|42|43|44|45
main: 12 46|47|48|49|50
main: 13 51|52|53|54|55
main: 14 56|57|58|59|60
main: 15 61|62|63|64|65
main: 16 66|67|68|69|70
main: 17 71|72|73|74|75
main: 18 76|77|78|79|80
main: 19 81|82|83|84|85
main: 20 86|87|88|89|90
main: 21 91|92|93|94|95
main: 22 96|97|98|99|100
Thread-2: 23 101|102|103|104|105
main: 24 101|102|103|104|105
main: 25 106|107|108|109|110
main: 26 111|112|113|114|115
main: 27 116|117|118|119|120
main: 28 121|122|123|124|125
Thread-2: 29 126|127|128|129|130
main: 30 126|127|128|129|130
Thread-2: 31 131|132|133|134|135
main: 32 136|137|138|139|140
Thread-2: 33 141|142|143|144|145
main: 34 146|147|148|149|150
main: 35 151|152|153|154|155
main: 36 156|157|158|159|160
main: 37 161|162|163|164|165
main: 38 166|167|168|169|170
main: 39 171|172|173|174|175
main: 40 176|177|178|179|180
Thread-2: 41 181|182|183|184|185
main: 42 186|187|188|189|190
Thread-2: 43 191|192|193|194|195
main: 44 191|192|193|194|195
main: 45 196|197|198|199|200
main: 46 201|202|203|204|205
main: 47 206|207|208|209|210
main: 48 211|212|213|214|215
Thread-2: 49 216|217|218|219|220
main: 50 221|222|223|224|225
Thread-2: 51 226|227|228|229|230
main: 52 231|232|233|234|235
Thread-2: 53 236|237|238|239|240
main: 54 241|242|243|244|245
Thread-2: 55 246|247|248|249|250
main: 56 251|252|253|254|255
Thread-2: 57 256|257|258|259|260
main: 58 261|262|263|264|265
Thread-2: 59 266|267|268|269|270
main: 60 271|272|273|274|275
Thread-2: 61 276|277|278|279|280
main: 62 276|277|278|279|280
main: 63 281|282|283|284|285
main: 64 286|287|288|289|290
main: 65 291|292|293|294|295
main: 66 296|297|298|299|300
加起来起码要100次,还有就是
Thread-2: 2 6|7|8|9|10
main: 3 6|7|8|9|10
这两行右边是插入的数据,实际上应该是要不同才对。我还没找到原因,难道是因为上一个事务(方法)还没来得及提交,下一个事务(方法)就开始执行了,所以就从数据找到了尚未修改的数据?可是这是为什么呢
main: 1 1|2|3|4|5
Thread-2: 2 6|7|8|9|10
main: 3 6|7|8|9|10
Thread-2: 4 11|12|13|14|15
main: 5 11|12|13|14|15
main: 6 16|17|18|19|20
Thread-2: 7 21|22|23|24|25
main: 8 26|27|28|29|30
main: 9 31|32|33|34|35
main: 10 36|37|38|39|40
main: 11 41|42|43|44|45
main: 12 46|47|48|49|50
main: 13 51|52|53|54|55
main: 14 56|57|58|59|60
main: 15 61|62|63|64|65
main: 16 66|67|68|69|70
main: 17 71|72|73|74|75
main: 18 76|77|78|79|80
main: 19 81|82|83|84|85
main: 20 86|87|88|89|90
main: 21 91|92|93|94|95
main: 22 96|97|98|99|100
Thread-2: 23 101|102|103|104|105
main: 24 101|102|103|104|105
main: 25 106|107|108|109|110
main: 26 111|112|113|114|115
main: 27 116|117|118|119|120
main: 28 121|122|123|124|125
Thread-2: 29 126|127|128|129|130
main: 30 126|127|128|129|130
Thread-2: 31 131|132|133|134|135
main: 32 136|137|138|139|140
Thread-2: 33 141|142|143|144|145
main: 34 146|147|148|149|150
main: 35 151|152|153|154|155
main: 36 156|157|158|159|160
main: 37 161|162|163|164|165
main: 38 166|167|168|169|170
main: 39 171|172|173|174|175
main: 40 176|177|178|179|180
Thread-2: 41 181|182|183|184|185
main: 42 186|187|188|189|190
Thread-2: 43 191|192|193|194|195
main: 44 191|192|193|194|195
main: 45 196|197|198|199|200
main: 46 201|202|203|204|205
main: 47 206|207|208|209|210
main: 48 211|212|213|214|215
Thread-2: 49 216|217|218|219|220
main: 50 221|222|223|224|225
Thread-2: 51 226|227|228|229|230
main: 52 231|232|233|234|235
Thread-2: 53 236|237|238|239|240
main: 54 241|242|243|244|245
Thread-2: 55 246|247|248|249|250
main: 56 251|252|253|254|255
Thread-2: 57 256|257|258|259|260
main: 58 261|262|263|264|265
Thread-2: 59 266|267|268|269|270
main: 60 271|272|273|274|275
Thread-2: 61 276|277|278|279|280
main: 62 276|277|278|279|280
main: 63 281|282|283|284|285
main: 64 286|287|288|289|290
main: 65 291|292|293|294|295
main: 66 296|297|298|299|300
#1
原因我懂了,因为事务之间是并发运行的,所以当然有问题。
那我就用synchronized关键来同步方法insertOrder,那么基本上每次调用service的insertOrder,应该都是按顺序来执行吧。
可是我测试了下,加上synchronized关键字,还是结果还是错的
那我就用synchronized关键来同步方法insertOrder,那么基本上每次调用service的insertOrder,应该都是按顺序来执行吧。
可是我测试了下,加上synchronized关键字,还是结果还是错的
@Override
public synchronized void insertOrder(SellingOrder sellingOrder) {
StringBuilder dealedBookId = new StringBuilder();
int bookId = sellingOrder.getBookId();
int amount = sellingOrder.getAmount();
List<DealedBook> dealedBooks =
dealedBookDao.getNoDealedBookByBookIdAndAmount(bookId, amount);
if (dealedBooks.size() != amount)
{
throw new NoEnoughBooksException("没有足够的书本"); // 错误抛出后,事务会回滚
}
for (DealedBook dealedBook : dealedBooks) {
dealedBook.setSelled(1);
dealedBook.setSelledDatetime(new Date());
dealedBookId.append("" + dealedBook.getId() + '|');
dealedBookDao.update(dealedBook); // 修改另外表的数据
}
if (dealedBookId.length() > 0)
dealedBookId = dealedBookId.deleteCharAt(dealedBookId.length()-1);
// 设置dealed_book_id字段的值
sellingOrder.setDealedBookIds(dealedBookId.toString());
sellingOrderDao.insert(sellingOrder); /
}
#2
spring里面的bean默认都是单例的,那么我上面的service实例自然都是同一个对象,我也输出查看过,确实是。
那么为什么加了synchronized,却不是按顺序执行
那么为什么加了synchronized,却不是按顺序执行
#3
下面是我测试出来的结果,我把两个线程分别设置了运行50次,实际上却会有线程少运行,不知道为什么。
加起来起码要100次,还有就是
Thread-2: 2 6|7|8|9|10
main: 3 6|7|8|9|10
这两行右边是插入的数据,实际上应该是要不同才对。我还没找到原因,难道是因为上一个事务(方法)还没来得及提交,下一个事务(方法)就开始执行了,所以就从数据找到了尚未修改的数据?可是这是为什么呢
main: 1 1|2|3|4|5
Thread-2: 2 6|7|8|9|10
main: 3 6|7|8|9|10
Thread-2: 4 11|12|13|14|15
main: 5 11|12|13|14|15
main: 6 16|17|18|19|20
Thread-2: 7 21|22|23|24|25
main: 8 26|27|28|29|30
main: 9 31|32|33|34|35
main: 10 36|37|38|39|40
main: 11 41|42|43|44|45
main: 12 46|47|48|49|50
main: 13 51|52|53|54|55
main: 14 56|57|58|59|60
main: 15 61|62|63|64|65
main: 16 66|67|68|69|70
main: 17 71|72|73|74|75
main: 18 76|77|78|79|80
main: 19 81|82|83|84|85
main: 20 86|87|88|89|90
main: 21 91|92|93|94|95
main: 22 96|97|98|99|100
Thread-2: 23 101|102|103|104|105
main: 24 101|102|103|104|105
main: 25 106|107|108|109|110
main: 26 111|112|113|114|115
main: 27 116|117|118|119|120
main: 28 121|122|123|124|125
Thread-2: 29 126|127|128|129|130
main: 30 126|127|128|129|130
Thread-2: 31 131|132|133|134|135
main: 32 136|137|138|139|140
Thread-2: 33 141|142|143|144|145
main: 34 146|147|148|149|150
main: 35 151|152|153|154|155
main: 36 156|157|158|159|160
main: 37 161|162|163|164|165
main: 38 166|167|168|169|170
main: 39 171|172|173|174|175
main: 40 176|177|178|179|180
Thread-2: 41 181|182|183|184|185
main: 42 186|187|188|189|190
Thread-2: 43 191|192|193|194|195
main: 44 191|192|193|194|195
main: 45 196|197|198|199|200
main: 46 201|202|203|204|205
main: 47 206|207|208|209|210
main: 48 211|212|213|214|215
Thread-2: 49 216|217|218|219|220
main: 50 221|222|223|224|225
Thread-2: 51 226|227|228|229|230
main: 52 231|232|233|234|235
Thread-2: 53 236|237|238|239|240
main: 54 241|242|243|244|245
Thread-2: 55 246|247|248|249|250
main: 56 251|252|253|254|255
Thread-2: 57 256|257|258|259|260
main: 58 261|262|263|264|265
Thread-2: 59 266|267|268|269|270
main: 60 271|272|273|274|275
Thread-2: 61 276|277|278|279|280
main: 62 276|277|278|279|280
main: 63 281|282|283|284|285
main: 64 286|287|288|289|290
main: 65 291|292|293|294|295
main: 66 296|297|298|299|300
加起来起码要100次,还有就是
Thread-2: 2 6|7|8|9|10
main: 3 6|7|8|9|10
这两行右边是插入的数据,实际上应该是要不同才对。我还没找到原因,难道是因为上一个事务(方法)还没来得及提交,下一个事务(方法)就开始执行了,所以就从数据找到了尚未修改的数据?可是这是为什么呢
main: 1 1|2|3|4|5
Thread-2: 2 6|7|8|9|10
main: 3 6|7|8|9|10
Thread-2: 4 11|12|13|14|15
main: 5 11|12|13|14|15
main: 6 16|17|18|19|20
Thread-2: 7 21|22|23|24|25
main: 8 26|27|28|29|30
main: 9 31|32|33|34|35
main: 10 36|37|38|39|40
main: 11 41|42|43|44|45
main: 12 46|47|48|49|50
main: 13 51|52|53|54|55
main: 14 56|57|58|59|60
main: 15 61|62|63|64|65
main: 16 66|67|68|69|70
main: 17 71|72|73|74|75
main: 18 76|77|78|79|80
main: 19 81|82|83|84|85
main: 20 86|87|88|89|90
main: 21 91|92|93|94|95
main: 22 96|97|98|99|100
Thread-2: 23 101|102|103|104|105
main: 24 101|102|103|104|105
main: 25 106|107|108|109|110
main: 26 111|112|113|114|115
main: 27 116|117|118|119|120
main: 28 121|122|123|124|125
Thread-2: 29 126|127|128|129|130
main: 30 126|127|128|129|130
Thread-2: 31 131|132|133|134|135
main: 32 136|137|138|139|140
Thread-2: 33 141|142|143|144|145
main: 34 146|147|148|149|150
main: 35 151|152|153|154|155
main: 36 156|157|158|159|160
main: 37 161|162|163|164|165
main: 38 166|167|168|169|170
main: 39 171|172|173|174|175
main: 40 176|177|178|179|180
Thread-2: 41 181|182|183|184|185
main: 42 186|187|188|189|190
Thread-2: 43 191|192|193|194|195
main: 44 191|192|193|194|195
main: 45 196|197|198|199|200
main: 46 201|202|203|204|205
main: 47 206|207|208|209|210
main: 48 211|212|213|214|215
Thread-2: 49 216|217|218|219|220
main: 50 221|222|223|224|225
Thread-2: 51 226|227|228|229|230
main: 52 231|232|233|234|235
Thread-2: 53 236|237|238|239|240
main: 54 241|242|243|244|245
Thread-2: 55 246|247|248|249|250
main: 56 251|252|253|254|255
Thread-2: 57 256|257|258|259|260
main: 58 261|262|263|264|265
Thread-2: 59 266|267|268|269|270
main: 60 271|272|273|274|275
Thread-2: 61 276|277|278|279|280
main: 62 276|277|278|279|280
main: 63 281|282|283|284|285
main: 64 286|287|288|289|290
main: 65 291|292|293|294|295
main: 66 296|297|298|299|300