代码的逻辑:

1)SProducer不停的产生number到queue中.
2)3个carrier不停的取出queue中的number.
3)如果queue中存在10个剩余number时,SProducer会停下来等Carrier消费一些后再生产.
4)如果Carrier发现queue中没有number时,会等待.
5)如果Carrier取出的数字末尾为4, 则会挑起罢工事件.
6)Carrier罢工会引发一个Negotiation线程进行谈判.
7)罢工阶段SProducer和所有Carrier均停工.
8)Negotiation如果发现取出的number首位为3或者7,将引发谈判失败.
9)如果谈判成功,则恢复工作,如果谈判失败,则破产,所有线程均退出.

注意:使用lock的时候一定要注意, lock()和unlock()方法一定要成对出现. 最好放到try{}finally{}中,这样,unlock()方法必会调到.倘若没有使用unlock()就return了,会导致线程死锁.

001 package concurrency;
002  
003 import java.util.ArrayList;
004 import java.util.concurrent.ArrayBlockingQueue;
005 import java.util.concurrent.locks.Condition;
006 import java.util.concurrent.locks.ReentrantLock;
007  
008 public class Producer extends Thread {
009     private final static ArrayBlockingQueue<String> numbers = new ArrayBlockingQueue<String>(10);
010     private final static ArrayList<Thread> threads = new ArrayList<Thread>();
011     private volatile boolean negotiating  = false;
012     private ReentrantLock negotiationLock = new ReentrantLock();
013     private Condition negotiationCondition = negotiationLock.newCondition();
014      
015     private class Negotiation implements Runnable {
016         private String number;
017         private Negotiation(String number) {
018             this.number = number;
019         }
020         public void run() {
021             try {
022                 System.out.println("Start negotiation...");
023                 sleep(5000);
024                 if (number.startsWith("7") || number.startsWith("3")) {
025                     System.out.println("Negotiation broken.");
026                     for (Thread t : threads) {
027                         t.interrupt();
028                     }
029                     System.out.println("Negotiation broken post handle.");
030                     return;
031                 }
032                 System.out.println("Negotiation succeeds.");
033             } catch (InterruptedException e) {
034                 System.out.println("Middle man is killed.");
035             }
036             negotiationLock.lock();
037             negotiating = false;
038             negotiationCondition.signalAll();
039             negotiationLock.unlock();
040         }
041     }
042      
043     private class Carrier implements Runnable {
044         private String name;
045         private Carrier(String name) {
046             this.name = name;
047         }
048         public void run() {
049             while(true) {
050                 try{
051                 negotiationLock.lock();
052                 while(negotiating) {
053                     try {
054                         System.out.println("Carrier ["+name+"] join stricks.");
055                         negotiationCondition.await();
056                     } catch (InterruptedException e) {
057                         System.out.println("Negotiation fails. Carrier [" + name + "] retires.");
058                         return;
059                     }
060                 }
061                 } finally {
062                 negotiationLock.unlock();
063                 }
064                 String number;
065                 try {
066                     number = numbers.take();
067                     System.out.println("Carrier [" + name + "] carries "+ number +" out of List;");
068                 } catch (InterruptedException e1) {
069                      System.out.println("Negotiation fails. Carrier [" + name + "] retires.");
070                      return;
071                 }
072                   
073                 if (number.endsWith("4")) {
074                     try {
075                     negotiationLock.lock();
076                     while (negotiating) {
077                         try {
078                             negotiationCondition.await();
079                         } catch (InterruptedException e) {
080                             System.out.println("Negotiation fails. Carrier [" + name + "] retires.");
081                             return;
082                         }
083                     }
084                     negotiating = true;
085                     System.out.println("Stricks happen on number:"+number);
086                     new Thread(new Negotiation(number)).start();
087                     } finally {
088                     negotiationLock.unlock();
089                     }
090                 }
091             }
092         }
093     }
094      
095     public void run() {
096         Thread a = new Thread(new Carrier("a"));
097         Thread b = new Thread(new Carrier("b"));
098         Thread c = new Thread(new Carrier("c"));
099         threads.add(this);
100         threads.add(a);
101         threads.add(b);
102         threads.add(c);
103          
104         a.start();
105         b.start();
106         c.start();
107          
108         this.produceNumbers();
109          
110     }
111      
112     private void produceNumbers() {
113         while (true) {
114             while(negotiating) {
115                 negotiationLock.lock();
116                 try {
117                     System.out.println("Stricking... Producer waiting for negotiation result.");
118                     negotiationCondition.await();
119                     System.out.println("Negotiation succeeds. Producer happy.");
120                 } catch (InterruptedException e) {
121                     System.out.println("Negotiation fails. Producer breaks up.");
122                     return;
123                 } finally {
124                     negotiationLock.unlock();
125                 }
126             }
127              
128             String number = ""+new java.util.Random().nextInt(47);
129            
130             try {
131                 numbers.put(number);
132                 System.out.println("Produce number " + number + " into List;");
133             } catch (InterruptedException e) {
134                 System.out.println("Negotiation fails. Producer breaks up.");
135                 return;
136             }
137         }
138     }
139          
140      
141     public static void main(String[] args) {
142         new Producer().start();
143     }
144 }