日期:2014-05-20  浏览次数:20816 次

生产消费线程问题,为什么要加synchronized
package com.zhangyg.thread.mytest;
public class ThreadCommunication {
public static void main(String[] args) {
Warehouse w = new Warehouse();
Proudcer p = new Proudcer(w);
Consumer c = new Consumer(w);
p.start();
c.start();
}
}
class Proudcer extends Thread {
Warehouse w;

Proudcer(Warehouse w) {
this.w = w;
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
// 生产商品
w.put(i);
//该语句引起问题
System.out.println("Producer 生产 " + i);
}
}
}

class Consumer extends Thread {
Warehouse w;

Consumer(Warehouse w) {
this.w = w;
}

@Override
public void run() {
while (true) {
//该语句引起问题
System.out.println("Customer "+" 消费 "+ w.get());
}
}
}
class Warehouse {
private int value;
boolean bFull = false; //仓库是否有商品
// 生产商品
public  void put(int value) {
if (!this.bFull) { // 仓库中没有商品
this.value = value;
this.bFull = true;
this.notify(); // 通知消费者进行消费
}
try {
this.wait(); // 等待消费者消费商品
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
// 消费商品
public  int get() {
if (!this.bFull) { //仓库中没有商品
try {
this.wait(); //等待生产者生产商品
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.bFull = false;
this.notify(); //通知生产者生产商品
return this.value;
}
}


请问上面的put和get方法为什么要枷锁,synchronized加在一个方法上,代表这个方法只能一个选择去运行吗,我感觉这边put只有生存者去调用,而get也只有消费者去调用,没有别的方法竞争啊,为什么要加synchronized,谢谢大神帮忙。

------解决方案--------------------
synchronized同步枷锁,你消费的商品有可能同一个客户要买,假如就剩下下一个商品了,两个人要买这一个商品,有一个人进入购买中,另一个人就会通知 没有 商品了,如果没有同步枷锁,一个商品卖了两个人,这个问题多囧啊,O(∩_∩)O~
------解决方案--------------------
你代码里斗大的字Thread看不见吗?

只有一个你继承Thread干吗?
------解决方案--------------------
如果方法没有加synchronized同步 你的代码运行肯定就是有问题的 因为 wait() 与 notify 只能在同步方法,或同步块中使用。

因为你的仓库的容量为1  所以,在你的类中同步的作用 主要是实现 存一次 取一次 的需求 。

------解决方案--------------------
给LZ举个简单的例子,你去火车站买票,现在比方说同时有多个窗口在卖,你买了一张 北京>>西安的 001号票,那其他的窗口就不可以再出一张相同的车票了,因为几个窗口都是在同时进行卖票这个操作的,所以为了防止错票的发生,必须加锁,也就是synchronized 或者 lock