pop()方法中的 notify(); index--; : 这可以导致去生产! return ArrWT[index]; 当执行完这三句代码后,退出了方法,就说明c释放了对象的锁:p线程已经醒来,就会和c线程抢占资源, 此时customer中的 System.out.println("消费了: "+wt); 代码还没有执行。 这个时候就要看p和c线程那个能抢到资源了。 出现你这种情况是p抢占到了资源了,因为允许生产,所以就生产了。 然后p生产满了,然后c线程接着执行它的代码,所以你会看到这样的情况。 修改了一下lz的代码- Java code
,lz好好揣摩一下!
public class TestProducerConsumer {
public static void main(String[] args) {
SyncStack ss = new SyncStack();
producer p = new producer(ss);
customer c = new customer(ss);
new Thread(p).start();
new Thread(c).start();
}
}
class WoTou {
int id = 0;
WoTou(int id) {
this.id = id;
}
public String toString() {
return "WoTou" + id;
}
}
class SyncStack {
int index = 0;
WoTou[] ArrWT = new WoTou[6];
public synchronized void push(WoTou wt) {
if (index >= ArrWT.length) {
try {
System.out.println("---------------满了,等待消费");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
ArrWT[index] = wt;
index++;
notify();//执行完自己的代码才去唤醒别人,要不别人就会和你抢cpu资源。
}
// 改变这无返回值
public synchronized void pop() {
if (index == 0) {
try {
System.out.println("没WoTou了,等待生产");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();//虽然我唤醒了那些等待的线程,但线程我还是持有对象的锁!!!
index--;
// return ArrWT[index];
// 改变如下:
System.out.println("消费了: " + ArrWT[index]);
}
}
class producer implements Runnable {
SyncStack ss = null;
producer(SyncStack ss) {
this.ss = ss;
}
public void run() {
for (int i = 0; i < 20; i++) {
WoTou wt = new WoTou(i);
ss.push(wt);
System.out.println("生产了:" + wt);
try {
Thread.sleep(200);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class customer implements Runnable {
SyncStack ss = null;
customer(SyncStack ss) {
this.ss = ss;
}
public void run() {
for (int i = 0; i < 20; i++) {
// WoTou wt=ss.pop();//锁定了对象
//执行到下面这句,你已经没有对象的锁!!!
// System.out.println("消费了: "+wt);
// 改变如下:
ss.pop();//锁定了对象
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
关键还是持有对象的锁!!!
|