【Java多线程系列四】控制线程执行顺序
假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现
- Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕
- CountDownLatch类:指定计数器,当计数器清零即取消阻塞
package com.concurrent.test; import java.util.concurrent.CountDownLatch; import org.junit.Assert; import org.junit.Test; /** * 规定线程的执行顺序 */ public class ThreadOrderTest { private long millisUnit = 1000; private int count = 2; class ThreadOrder { /* * join方法使多个线程依次执行 */ public long preserveOrderViaJoin() throws InterruptedException { long startMillis = System.currentTimeMillis(); Thread tmp; for (int i = 0; i < count; i++) { tmp = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(millisUnit); } catch (InterruptedException e) { e.printStackTrace(); } } }, "join-" + i); tmp.start(); tmp.join();//不停地监测线程是否执行完成,执行完成才继续往下 } return System.currentTimeMillis() - startMillis; } /* * CountdownLatch可同时阻塞多个线程,但它们可并发执行 */ public long preserveOrderViaCountdownLatch() throws InterruptedException { long startMillis = System.currentTimeMillis(); final CountDownLatch countDownLatch = new CountDownLatch(count); for (int i = 0; i < count; i++) { new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(millisUnit); } catch (InterruptedException e) { e.printStackTrace(); } //只要计数器清零,等待的线程就可以开始执行,于是可以达到并发的效果 countDownLatch.countDown(); } },"countDownLatch-" + i).start(); } countDownLatch.await(); return System.currentTimeMillis() - startMillis; } } @Test public void testPreserveOrderViaJoin() throws InterruptedException { ThreadOrder threadOrder = new ThreadOrder(); Assert.assertEquals(count, threadOrder.preserveOrderViaJoin() / millisUnit); } @Test public void testPreserveOrderViaCountdownLatch() throws InterruptedException { ThreadOrder threadOrder = new ThreadOrder(); Assert.assertEquals(1, threadOrder.preserveOrderViaCountdownLatch() / millisUnit); } }