java多线程工具类
从JDK 1.5开始,增加了java.util.concurrent包,它的引入大大简化了多线程的开发。
CountDownLatch
这个类可以实现某个线程阻塞,直到其他若干个线程完成任务后,才继续执行的效果。简单来说这是个计数器,当计数器减到0之后,释放阻塞的线程。
例如一个煮饭的例子
public class CountDownLatch_Demo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(3);
System.out.println("做饭前,需要材料");
//创建三个线程,分别去干不同的活
new Thread(new Cooker(countDownLatch,"买菜")).start();
new Thread(new Cooker(countDownLatch,"买肉")).start();
new Thread(new Cooker(countDownLatch,"买米")).start();
System.out.println("坐等材料买回来");
countDownLatch.await();
System.out.println("材料已经全部买回,可以开始做饭");
}
}
class Cooker implements Runnable{
CountDownLatch countDownLatch ;
String something;
Cooker(CountDownLatch countDownLatch ,String something){
this.countDownLatch = countDownLatch;
this.something = something ;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 正在 " + something );
try {
Thread.sleep(new Random().nextInt(10)*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("已完成 " + something);
countDownLatch.countDown();
}
}
- await() : 使当前线程在锁存计数器到零之前,一直阻塞,直到锁存计数器变为0之后,自动开放阻塞
- countDown() : 递减锁存器的计数,如果计数器达到 0 ,则放开所有等待的线程。
CyclicBarrier
这个类可以让多个线程在某一个节点进行阻塞,当所有线程到达指定位置后,再一起开放阻塞继续运行。
例如一个赛马的例子
public class CycliBarrier_Demo {
public static void main(String[] args) throws BrokenBarrierException, InterruptedException {
int count = 10;
CyclicBarrier cyclicBarrier = new CyclicBarrier(count);
for (int i =0 ; i<count ; i++){
new Thread(new Horse(cyclicBarrier,i)).start();
}
System.out.println("等待所有马准备就绪");
}
}
class Horse implements Runnable {
CyclicBarrier barrier;
Integer id;
Horse(CyclicBarrier cyclicBarrier, Integer id) {
this.barrier = cyclicBarrier;
this.id = id;
}
@Override
public void run() {
try {
Thread.sleep(new Random().nextInt(10)*1000);
System.out.println(id + " 号马 -----> 已经准备就绪");
barrier.await();
System.out.println(id + "号马---> " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 出发" );
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
CyclicBarrier和CountDownLatch 比较起来有什么区别呢。
1 、CountDownLatch : 都是一个线程,等待多个线程完成后再执行。CyclicBarrier : 线程组内每个线程在互相等待。
2、CountDownLatch是减计数方式,而CyclicBarrier是加计数方式。
3、CountDownLatch计数为0无法重置,而CyclicBarrier计数达到初始值,则可通过barrier.reset()重置。