java多线程经典的生产者 / 消费者实例,线程的协调。
1 package java语言程序设计进阶篇; 2 3 import java.util.concurrent.ExecutorService; 4 import java.util.concurrent.Executors; 5 import java.util.concurrent.locks.Condition; 6 import java.util.concurrent.locks.Lock; 7 import java.util.concurrent.locks.ReentrantLock; 8 9 public class Chapter30_7 { 10 private static Buffer buffer = new Buffer(); 11 public static void main(String[] args){ 12 ExecutorService executor = Executors.newFixedThreadPool(2); 13 executor.execute(new ProducerTask()); 14 executor.execute(new ConsumerTask()); 15 executor.shutdown(); 16 } 17 18 public static class ProducerTask implements Runnable{ 19 public void run(){ 20 try{ 21 int i = 1; 22 while(true){ 23 System.out.println("Producer writes " + i); 24 buffer.write(i++); 25 Thread.sleep((int)(Math.random() * 10000)); 26 } 27 } 28 catch (InterruptedException ex){ 29 ex.printStackTrace(); 30 } 31 } 32 } 33 34 public static class ConsumerTask implements Runnable{ 35 public void run(){ 36 try{ 37 while(true){ 38 System.out.println("\t\tConsumer reads " + buffer.read()); 39 Thread.sleep((int)(Math.random() * 10000)); 40 } 41 } 42 catch(InterruptedException ex){ 43 ex.printStackTrace(); 44 } 45 } 46 } 47 48 public static class Buffer{ 49 private static final int CAPACITY = 1; //缓冲区的大小 50 private java.util.LinkedList<Integer> queue = new java.util.LinkedList<>(); 51 private static Lock lock = new ReentrantLock(); 52 private static Condition notFull = lock.newCondition(); 53 private static Condition notEmpty = lock.newCondition(); 54 55 public void write(int value){ 56 lock.lock(); 57 try{ 58 while(queue.size() == CAPACITY){ 59 System.out.println("Wait for notFull condition"); 60 notFull.await(); 61 } 62 queue.offer(value); 63 notEmpty.signal(); 64 } 65 catch(InterruptedException ex){ 66 ex.printStackTrace(); 67 } 68 finally { 69 lock.unlock(); 70 } 71 } 72 73 public int read(){ 74 int value = 0;//存放被删除数 75 lock.lock(); 76 try{ 77 while(queue.isEmpty()){ 78 System.out.println("\t\tWait for notEmpty condition"); 79 notEmpty.await(); 80 } 81 value = queue.remove(); 82 notFull.signal(); 83 } 84 catch (InterruptedException ex){ 85 ex.printStackTrace(); 86 } 87 finally { 88 lock.unlock(); 89 return value; 90 } 91 } 92 } 93 }