?
1.CountDownLatch
? ? ?这个工具主要是将一个任务分解,等待所有的子任务完成才会做下面的操作,这个等待的操作主要是await控制的。计数值不能被重置,需要重置的情况需要使用CyclicBarrier。
? ? ?下面的例子发现所有的线程都执行完成,才会打印done。
? ? ?如果注释掉latch.await(); ?发现done是在中间打印的,没有等待子任务都完成就执行了。
package concurrent; import java.util.concurrent.CountDownLatch; public class TestCountDownLatch { public static void main(String[] args) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(10); for(int i= 0; i<10;i++){ new Thread(new Runnable() { public void run() { // TODO Auto-generated method stub System.out.println(Thread.currentThread().getName() +"--> begin"); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"--> end"); latch.countDown(); } },String.valueOf(i)).start(); } latch.await(); System.out.println("done------------"); } }
?
?
2.CyclicBarrier?
? ?这个工具主要是每个任务有多个阶段,如第三个阶段开始的前提必须是第二个阶段的所有人完成了任务。
可以向CyclicBarrier 其中注入runnable对象,这样计数器到达0时候自动触发该事件,同时计数值重置。
? ?
package concurrent; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class TestCyclicBarrier { private final static CyclicBarrier cyclicBarrier = new CyclicBarrier(10,new Runnable() { public void run() { System.out.println("新的任务开始啦"); } }); public static void main(String[] args) throws InterruptedException { for(int i= 0; i<10;i++){ new Thread(new Runnable() { public void run() { // TODO Auto-generated method stub System.out.println(Thread.currentThread().getName() +"--> begin run"); try { cyclicBarrier.await(); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (BrokenBarrierException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.out.println(Thread.currentThread().getName() +"--> begin jump"); try { cyclicBarrier.await(); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (BrokenBarrierException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.out.println(Thread.currentThread().getName() +"--> begin walk"); try { cyclicBarrier.await(); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (BrokenBarrierException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"--> end"); } },String.valueOf(i)).start(); } } }
? ? 执行结果
? ?
0--> begin run 3--> begin run 2--> begin run 1--> begin run 5--> begin run 4--> begin run 7--> begin run 6--> begin run 9--> begin run 8--> begin run 新的任务开始啦 8--> begin jump 3--> begin jump 1--> begin jump 4--> begin jump 0--> begin jump 9--> begin jump 6--> begin jump 7--> begin jump 5--> begin jump 2--> begin jump 新的任务开始啦 2--> begin walk 1--> begin walk 9--> begin walk 6--> begin walk 4--> begin walk 3--> begin walk 8--> begin walk 5--> begin walk 7--> begin walk 0--> begin walk 新的任务开始啦 7--> end 5--> end 3--> end 9--> end 6--> end 8--> end 4--> end 2--> end 1--> end 0--> end
?
? ?3.Semaphor
? ? ? 计数器的价值在于控制只能有n个子任务访问某个资源。如下面的例子,只能同时存在三个进程。
? ? ?
package concurrent; import java.util.concurrent.Semaphore; public class TestSemaphor { static Semaphore semaphore = new Semaphore(3, true); public static void main(String[] args) { for(int i= 0; i<10;i++){ new Thread(new Runnable() { public void run() { // TODO Auto-generated method stub try { semaphore.acquire(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() +"--> begin "); try { Thread.currentThread().sleep(10000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // System.out.println(Thread.currentThread().getName()+"--> end"); semaphore.release(); } },String.valueOf(i)).start(); } } }
?
原文:http://labreeze.iteye.com/blog/2166119