Thread.join()
CountDownLatch.await()
CyclicBarrier.await()
三者都是用来控制程序的“流动” 可以让程序“堵塞”在某几个点 以利用经由多线程操作后的某些最终结果
eg1:
1 public class joinTest { 2 3 private static Thread[] ts = new Thread[10]; 4 private static AtomicInteger ai = new AtomicInteger(0); 5 6 public joinTest() { 7 for (int i = 0; i < 10; i++) { 8 ts[i] = new Thread() { 9 @Override 10 public void run() { 11 try { 12 Thread.sleep(100); 13 }catch (Exception e){ 14 15 } 16 ai.incrementAndGet(); 17 } 18 }; 19 } 20 } 21 22 23 24 25 public static void main(String[] args) throws Exception { 26 27 new joinTest(); 28 29 for (int i = 0; i < 10; i++) { 30 ts[i].start(); 31 } 32 33 for (int i = 0; i < 10; i++) { 34 ts[i].join(); 35 } 36 37 System.out.println(ai); 38 39 } 40 41 }
此时输出为10
注意在run方法中的sleep操作,此时必须写到try/catch代码块内,因为异常不能跨线程传播 所以不能写在方法尾部throws!
eg2:
public class controlThread { private static final int ThreadCount = 500; private static AtomicInteger result = new AtomicInteger(0); private static CountDownLatch endCount = new CountDownLatch(ThreadCount); static void helper(){
for(int i=0;i<500;i++){ new Thread() { @Override public void run() { result.incrementAndGet(); endCount.countDown(); } }.start(); } } public static void main(String[] args) throws Exception{
new Thread(){ @Override public void run(){ helper(); } }.start(); endCount.await(); //Thread.sleep(10); print(result); } }
此时result结果为500
如果注释掉await() 加上sleep 则数值随机
全都注释掉一般情况为0
eg3:
public class cyclicBarrierTest { private static CyclicBarrier cyclic = new CyclicBarrier(5,new BarrierRun()); private static boolean flag = false; static class BarrierRun implements Runnable{ @Override public void run(){ if(!flag) print("we five are ready!"); else print("we five are ready again!"); } } public static void main(String[] args) throws Exception { for (int i = 0; i < 5; i++) { new Thread() { @Override public void run() { try { print(Thread.currentThread()+"'s worker has comed"); cyclic.await(); flag = true ; print(Thread.currentThread()+"wait you five so long!"); cyclic.await(); } catch (Exception e) { e.printStackTrace(); } } }.start(); } } }
只有当指定数目的线程进入到cyclic.await()方法处,才会让各个线程继续执行。 而且该方法可以复用。
这里如果某一个线程被中断,其他程序将不会愚蠢的等待 人到齐了 再执行接下来的任务 此时程序报错