前面已经把并发编程的基础知识讲的差不多了,这章主要介绍一下JAVA中其它一些关于并发编程的类库,主要有一下几个类库。
- CountDownLatch
- CyclicBarrier
- BlockingQueue
- ScheduleExecutor
- Semaphore
- Exchanger
1. CountDownLatch
该类主要是同步一个或多个任务,强制一个或多个任务等待其它任务执行的一组操作完成。可以给该对象设置一个初始计数值,当计数值不为0时,调用该对象的await()方法就会阻塞,调用counDown()方法会让计数值减1,当计数值为0时阻塞任务会被唤醒。其典型用法就是将一个程序分成多个独立的任务,并给CountDownLatch设定一个初始值,该初始值应该为首先需要执行的线程的个数(比如赛跑,5个运动员都做好准备之后,裁判才能打枪,这时初始值应该设置为5)。一些任务需要等待其它任务先完成或者其它任务的一部分完成,那么可以待用await()将自己挂起。而另一些任务的某些操作完成时调用countDown()方法来减小计数值,等待计数值为0时,挂起的任务则则认为当前所有的条件以满足继续执行的需要了,则可以继续运行。注意:计数值只能被设置一次且在new的时候就要指定初值,而且该对象只能使用一次,如果想重复使用,请考虑CyclicBarrier
1 package com.dy.xidian; 2 3 import java.util.Random; 4 import java.util.concurrent.CountDownLatch; 5 import java.util.concurrent.ExecutorService; 6 import java.util.concurrent.Executors; 7 import java.util.concurrent.TimeUnit; 8 9 class TaskPortion implements Runnable { 10 private static int counter = 0; 11 private final int id = counter++; 12 private static Random rand = new Random(47); 13 private final CountDownLatch latch; 14 15 public TaskPortion(CountDownLatch latch) { 16 super(); 17 this.latch = latch; 18 } 19 20 @Override 21 public void run() { 22 try { 23 doWork(); 24 latch.countDown(); 25 } catch (InterruptedException e) { 26 } 27 28 } 29 30 public void doWork() throws InterruptedException { 31 TimeUnit.MILLISECONDS.sleep(rand.nextInt(2000)); 32 System.out.println(this + "completed"); 33 } 34 35 public String toString() { 36 return String.format("%1$-3d", id); 37 } 38 } 39 40 class WaitingTask implements Runnable { 41 private static int counter = 0; 42 private final int id = counter++; 43 private final CountDownLatch latch; 44 45 public WaitingTask(CountDownLatch latch) { 46 super(); 47 this.latch = latch; 48 } 49 50 @Override 51 public void run() { 52 try { 53 latch.await(); 54 System.out.println("Latch barrier passed for " + this); 55 } catch (InterruptedException e) { 56 System.out.println(this + " interrupted"); 57 } 58 } 59 60 public String toString() { 61 return String.format("WaitingTask %1$-3d ", id); 62 } 63 } 64 public class CountDownLatchDemo { 65 static final int SIZE = 100; 66 public static void main(String[] args) { 67 ExecutorService exec = Executors.newCachedThreadPool(); 68 CountDownLatch latch = new CountDownLatch(SIZE); 69 for (int i = 0; i < 10; i++) 70 exec.execute(new WaitingTask(latch)); 71 for (int i = 0; i < SIZE; i++) 72 exec.execute(new TaskPortion(latch)); 73 System.out.println("Launched all tasks"); 74 exec.shutdownNow(); 75 } 76 }