Synchronizer
控制多个线程的流程,比如线程执行到某一个点的时候是等待还是通过。 JDK中自带了信号量,关卡,闭锁
闭锁CoutDownLatch
达到最终状态前是关闭的,所有线程在此阻塞, 达到最终状态后开放,并且不可以再修改,所有线程进入可运行状态。
很适合,等待初始化, 等待依赖等等场景。
如:
/*** 设置countDownLatch的初始值,* 用await()来等待* 用countDown来倒计时 --初始值* 当初始值为0时await()等待被notify*/
public class TestLatch {public static void main(String[] args) {final CountDownLatch latch = new CountDownLatch(1);final String[] datas = new String[3];new Thread(){@Overridepublic void run() {try {System.out.println("等待初始化");latch.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("初始化完成。开始执行");for (String data : datas) {System.out.println(data);}}}.start();try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}datas[0] = "我";datas[1] = "爱";datas[2] = "你";System.out.println("初始化完成");latch.countDown();}
}
信号量
适用于连接池等场景
/*** 创建一个含有固定许可数的信号量* 线程用acquire()标记获得了一个许可,切许可-1,当许可为0时等待,* 用release来释放许可,许可+1,其他等待的线程可以获得许可了。*/
public class TestSemaphore {public static void main(String[] args) {final Semaphore semaphore = new Semaphore(5);for (int i = 0; i < 20; i++) {new Thread("thread" + i){@Overridepublic void run() {try {semaphore.acquire();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(getName() + "正在执行");try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}semaphore.release();;}}.start();}}
}
关卡
与闭锁不同的是,闭锁等待状态,而关卡是等待线程。
特别适用于把一个计算拆分成多个进行计算,最后再进行整合。
/*** 关卡* 定义所有线程都到关卡之后的行为及关卡中包含的线程数量** 各个线程使用await方法来表示已经到这个关卡等着了** 当指定数目的线程等着了,那么就开放关卡, 所有线程及刚才定义的行为都继续执行*/
public class TestBarrier {public static void main(String[] args) {final String[] friends = new String[]{"1", "2", "3"};final CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {@Overridepublic void run() {System.out.println("出发");}});for (final String friend : friends) {new Thread(){@Overridepublic void run() {System.out.println(friend + "到集合点了");try {cyclicBarrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}System.out.println(friend + "出发");}}.start();}}
}
打印如下:
1到集合点了
3到集合点了
2到集合点了
出发
2出发
3出发
1出发