一:倒计时器:countDownLatch
countDownLatch是一个实用的多线程控制工具类。又称为倒计时器,通常用来控制线程等待,可以让某一个线程等待直到倒计时结束,再开始执行。
解释:也就是一个任务在开始之前要等待一系列准备条件完成时,然后再开始执行,如火箭发射要进行各种仪器检查无误之后才能进行发射操作,而这个等待过程就是倒计时器的操作原理。
解析:countDown()用于通知countDownLatch,一个线程已经完成了任务,倒计时器可以减一了。方法countDownLatch.await();要求主线程等待所有10个检查任务全部完成,只有任务都完成了,主线程才继续执行。
二:循环栅栏:CyclicBarrier
CyclicBarrier 是另外一种多线程并发控制实用工具。和CountDownLatch累死,也可以实现线程间的计数等待,比countDownLatch更加复杂强大。
栅栏是一种障碍物,这里用来阻止线程继续执行,要求线程在栅栏处等待,cyclic为循环,可以反复使用,比如计数器设置为10,凑齐第一批后,计数器会归零,然后接着凑齐下一批10个线程。
一:线程阻塞工具类:LockSupport
是一个非常实用的线程阻塞工具,可以在线程内任意位置让线程阻塞,和Thread.suspend()相比,弥补了由于resume()在前发生,导致线程无法继续执行的情况。和object.wait()相比,不需要先获得某个对象的锁,也不会抛出InterruptedException异常。
LockSupport的静态方法 park()可以阻塞当前线程,类似还有parkNanos()、parkUntil()等方法,实现了一个限时等待。
代码:
public class ThreadUtils { public static Object u = new Object(); static ChangeObjectThread t1 = new ChangeObjectThread("t1"); static ChangeObjectThread t2 = new ChangeObjectThread("t2"); public static class ChangeObjectThread extends Thread{ public ChangeObjectThread(String name){ super.setName(name); } public void run(){ synchronized (u){ System.out.println("in "+getName()); LockSupport.park(); } } } public static void main(String[] args) throws InterruptedException { t1.start(); Thread.sleep(100); t2.start(); LockSupport.unpark(t1); System.out.println("释放t1"); LockSupport.unpark(t2); t1.join(); t2.join(); } }
使用park()阻塞住了线程,只有使用unpark()解除阻塞之后,其他线程才能进入。
三:线程复用:线程池