这是孙卫琴《Java面向对象编程》中的关于线程同步的生产者-消费者问题的示例。但运行一下就卡死不动了。我猜可能是发生了死锁。但怎么都看不出问题在哪。肯请高手指点迷津!!!!!!!public class SyncTest {
public static void main(String[] args ) {
Stack stack1 = new Stack("stack1");
Producer producer1 = new Producer( stack1, "producer1");
Consumer consumer1 = new Consumer(stack1, "consumer1");
Consumer consumer2 = new Consumer(stack1, "cosumer2"); Stack stack2 = new Stack("stack2");
Producer producer2 = new Producer(stack2, "producer2");
Producer producer3 = new Producer(stack2, "producer3");
Consumer consumer3 = new Consumer(stack2, "consumer3");
}
}/** 生产者线程*/
class Producer extends Thread {
private Stack theStack;
public Producer ( Stack s, String name ) {
super(name);
theStack = s;
start(); //启动自身生产者线程
}
public void run() {
String goods;
for (int i = 0 ; i < 150; i++ ) {
goods = "goods" +(theStack.getPoint() + 1);
theStack.push(goods); System.out.println(getName() + " : push " + goods + "to " + theStack.getName() ); yield();
}
}
}/** 消费者线程*/
class Consumer extends Thread { //遇到数组越界没有捕捉机制,会终止当前运行的线程
private Stack theStack;
public Consumer ( Stack s, String name ) {
super(name);
theStack = s;
start();
} public void run() {
String goods;
for (int i = 0; i < 150; i++ ) {
goods = theStack.pop();
System.out.println(getName() + " : pop " + goods + " from " + theStack.getName() ); yield();
}
}
}/** 堆栈*/
class Stack {
private String name;
private String[] buffer = new String[100];
int point = -1; public Stack(String name) { this.name = name; }
public String getName () { return name; } public synchronized int getPoint() { return point; } public synchronized String pop() {
this.notifyAll();
while(point == -1) {
System.out.println(Thread.currentThread().getName() + " : wait");
try {
this.wait();
}catch(InterruptedException e) { throw new RuntimeException(e); }
}
String goods = buffer[point];
buffer[point] = null;
Thread.yield();
point -- ;
return goods;
} public synchronized void push(String goods) {
this.notifyAll(); while(point == buffer.length - 1) {
System.out.println(Thread.currentThread().getName() + ": wait");
try {
this.wait();
}catch(InterruptedException e) { throw new RuntimeException(e); }
}
point++;
Thread.yield();
buffer[point] = goods;
}
}
public static void main(String[] args ) {
Stack stack1 = new Stack("stack1");
Producer producer1 = new Producer( stack1, "producer1");
Consumer consumer1 = new Consumer(stack1, "consumer1");
Consumer consumer2 = new Consumer(stack1, "cosumer2"); Stack stack2 = new Stack("stack2");
Producer producer2 = new Producer(stack2, "producer2");
Producer producer3 = new Producer(stack2, "producer3");
Consumer consumer3 = new Consumer(stack2, "consumer3");
}
}/** 生产者线程*/
class Producer extends Thread {
private Stack theStack;
public Producer ( Stack s, String name ) {
super(name);
theStack = s;
start(); //启动自身生产者线程
}
public void run() {
String goods;
for (int i = 0 ; i < 150; i++ ) {
goods = "goods" +(theStack.getPoint() + 1);
theStack.push(goods); System.out.println(getName() + " : push " + goods + "to " + theStack.getName() ); yield();
}
}
}/** 消费者线程*/
class Consumer extends Thread { //遇到数组越界没有捕捉机制,会终止当前运行的线程
private Stack theStack;
public Consumer ( Stack s, String name ) {
super(name);
theStack = s;
start();
} public void run() {
String goods;
for (int i = 0; i < 150; i++ ) {
goods = theStack.pop();
System.out.println(getName() + " : pop " + goods + " from " + theStack.getName() ); yield();
}
}
}/** 堆栈*/
class Stack {
private String name;
private String[] buffer = new String[100];
int point = -1; public Stack(String name) { this.name = name; }
public String getName () { return name; } public synchronized int getPoint() { return point; } public synchronized String pop() {
this.notifyAll();
while(point == -1) {
System.out.println(Thread.currentThread().getName() + " : wait");
try {
this.wait();
}catch(InterruptedException e) { throw new RuntimeException(e); }
}
String goods = buffer[point];
buffer[point] = null;
Thread.yield();
point -- ;
return goods;
} public synchronized void push(String goods) {
this.notifyAll(); while(point == buffer.length - 1) {
System.out.println(Thread.currentThread().getName() + ": wait");
try {
this.wait();
}catch(InterruptedException e) { throw new RuntimeException(e); }
}
point++;
Thread.yield();
buffer[point] = goods;
}
}
private String consumerName = null;
private StoreHouse storeHouse = null;
public Consumer(String consumerName, StoreHouse storeHouse) {
this.consumerName = consumerName;
this.storeHouse = storeHouse;
}
public void setConsumerName(String consumerName) {
this.consumerName = consumerName;
}
public String getConsumerName() {
return consumerName;
}
public synchronized void consumerProduct() {
while (true) {
Product p = storeHouse.pop();
//System.out.println(getConsumerName() + " 消费了 " + p);
storeHouse.print();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
return;
}
}
}
public void run() {
consumerProduct();
}
} class Producer extends Thread {
private static int i = 0;
private String producerName = null;
private StoreHouse storeHouse = null;
public Producer(String producerName, StoreHouse storeHouse) {
this.producerName = producerName;
this.storeHouse = storeHouse;
}
public void setProducerName(String producerName) {
this.producerName = producerName;
}
public String getProducerName() {
return producerName;
}
public synchronized void produceProduct() {
while (true) {
i++;
Product pro = new Product(i);
storeHouse.push(pro);
//System.out.println(getProducerName() + " 生产了 " + pro);
storeHouse.print();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
}
}
public void run() {
produceProduct();
}
} class Product {
private int productId = 0;
public Product(int productId) {
this.productId = productId;
}
public synchronized int getProductId() {
return productId;
}
public String toString() {
return Integer.toString(productId);
}
} class StoreHouse {
private int pushPoint = 0;
private int popPoint = 0;
private int size = 0;
private final int fifoSize = 2;
private Product[] products = new Product[10];
public synchronized void push(Product product) {
while (size == fifoSize) {
try {
System.out.println("仓库已满,正等待消费...");
wait();
} catch (InterruptedException e) {
System.out.println("stop push product because other reasons");
}
}
System.out.println("可以生产");
products[pushPoint] = product;
System.out.println("生产了" + product);
pushPoint = (pushPoint + 1) % fifoSize;
size++;
System.out.print("########");
print();
this.notifyAll();
}
public synchronized Product pop() {
Product pro = null;
while (size == 0) {
try {
System.out.println("仓库已空,正等待生产...");
wait();
} catch (InterruptedException e) {
System.out.println("stop push product because other reasons");
}
}
System.out.println("可以消费");
pro = products[popPoint];
System.out.println("消费了"+ pro);
popPoint = (popPoint + 1) % fifoSize;
size--;
System.out.print("&&&&&&&&&&");
print();
this.notifyAll();
return pro;
}
public synchronized void print(){
System.out.println("pPonit = " + this.pushPoint + ", cPoint =" + this.popPoint + ", size is " + this.size);
}
}public class Test { StoreHouse storeHouse = new StoreHouse();
Producer producer1 = new Producer("生产者1", storeHouse);
Producer producer2 = new Producer("生产者2", storeHouse);
Producer producer3 = new Producer("生产者3", storeHouse);
Consumer comsumer1 = new Consumer("消费者1", storeHouse);
Consumer comsumer2 = new Consumer("消费者2", storeHouse);
public Test(){
producer1.start();
comsumer1.start();
producer2.start();
producer3.start();
comsumer2.start();
}
public static void main(String[] args) {
new Test();
}
}
线程停在那里等待 有了资源当然要唤醒才能继续
public class SyncTest2 {
public static void main(String[] args ) {
Stack stack1 = new Stack("stack1");
Producer producer1 = new Producer( stack1, "producer1");
Consumer consumer1 = new Consumer(stack1, "consumer1");
Consumer consumer2 = new Consumer(stack1, "cosumer2"); //Stack stack2 = new Stack("stack2");
//Producer producer2 = new Producer(stack2, "producer2");
//Producer producer3 = new Producer(stack2, "producer3");
//Consumer consumer3 = new Consumer(stack2, "consumer3");
}
}/** 生产者线程*/
class Producer extends Thread {
private Stack theStack;
public Producer ( Stack s, String name ) {
super(name);
theStack = s;
start(); //启动自身生产者线程
}
public void run() {
String goods;
for ( int i = 0 ;i < 200 ; i++ ) {
goods = "goods" +(theStack.getPoint() + 1);
theStack.push(goods); System.out.println(getName() + " : push " + goods + "to " + theStack.getName() );
yield();
}
}
}/** 消费者线程*/
class Consumer extends Thread { //遇到数组越界没有捕捉机制,会终止当前运行的线程
private Stack theStack;
public Consumer ( Stack s, String name ) {
super(name);
theStack = s;
start();
} public void run() {
String goods;
for ( int i = 0 ;i < 200 ; i++ ) {
goods = theStack.pop();
System.out.println(getName() + " : pop " + goods + " from " + theStack.getName() );
yield();
}
}
}/** 堆栈*/
class Stack {
private String name;
private String[] buffer = new String[100];
int point = -1; public Stack(String name) { this.name = name; }
public String getName () { return name; } public synchronized int getPoint() { return point; } public synchronized String pop() {
this.notifyAll();
while(point == -1) {
System.out.println(Thread.currentThread().getName() + " : wait");
//this.notifyAll(); //若把notifyAll()移到这里,就能一直地执行下去了……
try { //生产者执行了200次后撤销,正好这一刻,剩下两个消费者,其中一个消费者(假设是consumer1)获得对象锁,并通知另一个消费者,使其在对象锁上等待。
//consumer1执行wait()进入对象池中并释放对象锁。然后consumer2获得对象锁,并通知consuer1,使其在对象锁上等待。
//然后consumer2执行wait()进入对象池中并释放对象锁。接着consumer1又获得对象锁,但这次是在while循环体内,没有机会执行notifyAll(),这次没有线程能唤醒他了。
this.wait(); //而此刻consumer2也在对象池中。所以两个线程都在对象池中,没办法唤醒,程序就这样停在这里了。
//System.out.println("I'm after this.wait()");
}catch(InterruptedException e) { throw new RuntimeException(e); }
}
String goods = buffer[point];
buffer[point] = null;
Thread.yield();
point -- ; return goods; } public synchronized void push(String goods) {
this.notifyAll(); while(point == buffer.length - 1) {
System.out.println(Thread.currentThread().getName() + ": wait");
//this.notifyAll();
try {
//Thread.sleep(50);
this.wait();
}catch(InterruptedException e) { throw new RuntimeException(e); }
}
point++;
Thread.yield();
buffer[point] = goods;
}
}