进行多线程其实不麻烦,麻烦的是对事务的控制处理,比如全滚或者部分回滚
CountDownLatch是一个同步工具类,它使用给定的 count初始化, await()方法会一直阻塞,直到计数器的值变为零(由于 countDown()方法被调用导致的),这时会释放所有等待的线程,且之后再调用 await()方法会直接返回,不会阻塞。 CountDownLatch是一个 一次性的类,计数器不能被重置,这一点与 CyclicBarrier不同。另一个不同点是: CountDownLatch是让所有线程 等待计数器的值变为零再继续执行;而 CyclicBarrier是要 等待指定个数的线程到达 Barrier 的位置再一起继续执行。
CountDownLatch 提供了一个构造方法,你必须指定其初始值,还指定了 countDown 方法,这个方法的作用主要用来减小计数器的值,当计数器变为 0 时,在 CountDownLatch 上 await 的线程就会被唤醒,继续执行其他任务。当然也可以延迟唤醒,给 CountDownLatch 加一个延迟时间就可以实现。
1.CountDownLatch原理就是分配多条线程,主线程进行阻塞,待全部线程完成,主线程才执行
主要用到的方法就是创建对象的时候我们穿入的是线程数,然后每条线程执行完的时候执行
countDown() 进行计数,代表已完成线程+1
await() 则代表主线程阻塞,等待所有线程完成开往下执行
以下是部分回滚的demo
1.事务开启手动事务,根据业务具体回滚
//开启多线程
List<String> ids = new ArrayList<>(10);
CountDownLatch countDownLatch = new CountDownLatch(ids.size());
for (final String id : ids) {
//这里线程池自己创建一个给spring容器托管
//noticeThread则是自己创建的线程类
threadPoolTaskExecutor.execute(new NoticeThread() {
@Override
public void run() {
//开启手动事务
//如果是spring则DataSourceTransactionManager注入就行,具体的事务管理器则按照不同的第三方数据库具体调整
TransactionStatus status = dataSourceTransactionManager.getTransaction(
//这里事务传播机制用的是每个都是创建一个新的事务,这样事务隔离性就不会互相干扰事务了
new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW));
try{
//执行具体业务,然后提交事务
dataSourceTransactionManager.commit(status);
}catch(Exception e){
//打印日志和回滚单个事务,回滚程度根据业务需求来
dataSourceTransactionManager.rollback(status);
} finally {
//无论怎样,最后这条线程跑完,就执行countDown代表线程跑完了一条
countDownLatch.countDown();
}
}
});
}
countDownLatch.await();