代码的逻辑:
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 |
} |