代码的逻辑:
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了,会导致线程死锁.
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; |
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(); |
015 | private class Negotiation implements Runnable { |
016 | private String number; |
017 | private Negotiation(String number) { |
018 | this .number = number; |
022 | System.out.println( "Start negotiation..." ); |
024 | if (number.startsWith( "7" ) || number.startsWith( "3" )) { |
025 | System.out.println( "Negotiation broken." ); |
026 | for (Thread t : threads) { |
029 | System.out.println( "Negotiation broken post handle." ); |
032 | System.out.println( "Negotiation succeeds." ); |
033 | } catch (InterruptedException e) { |
034 | System.out.println( "Middle man is killed." ); |
036 | negotiationLock.lock(); |
038 | negotiationCondition.signalAll(); |
039 | negotiationLock.unlock(); |
043 | private class Carrier implements Runnable { |
045 | private Carrier(String name) { |
051 | negotiationLock.lock(); |
054 | System.out.println( "Carrier [" +name+ "] join stricks." ); |
055 | negotiationCondition.await(); |
056 | } catch (InterruptedException e) { |
057 | System.out.println( "Negotiation fails. Carrier [" + name + "] retires." ); |
062 | negotiationLock.unlock(); |
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." ); |
073 | if (number.endsWith( "4" )) { |
075 | negotiationLock.lock(); |
076 | while (negotiating) { |
078 | negotiationCondition.await(); |
079 | } catch (InterruptedException e) { |
080 | System.out.println( "Negotiation fails. Carrier [" + name + "] retires." ); |
085 | System.out.println( "Stricks happen on number:" +number); |
086 | new Thread( new Negotiation(number)).start(); |
088 | negotiationLock.unlock(); |
096 | Thread a = new Thread( new Carrier( "a" )); |
097 | Thread b = new Thread( new Carrier( "b" )); |
098 | Thread c = new Thread( new Carrier( "c" )); |
108 | this .produceNumbers(); |
112 | private void produceNumbers() { |
115 | negotiationLock.lock(); |
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." ); |
124 | negotiationLock.unlock(); |
128 | String number = "" + new java.util.Random().nextInt( 47 ); |
132 | System.out.println( "Produce number " + number + " into List;" ); |
133 | } catch (InterruptedException e) { |
134 | System.out.println( "Negotiation fails. Producer breaks up." ); |
141 | public static void main(String[] args) { |
142 | new Producer().start(); |