黑马程序员技术交流社区

标题: 生产消费线程问题,为什么要加synchronized [打印本页]

作者: tonygone    时间: 2013-7-18 12:57
标题: 生产消费线程问题,为什么要加synchronized
本帖最后由 杨兴庭 于 2013-7-18 21:26 编辑
  1. package com.zhangyg.thread.mytest;
  2. public class ThreadCommunication {
  3.     public static void main(String[] args) {
  4.         Warehouse w = new Warehouse();
  5.         Proudcer p = new Proudcer(w);
  6.         Consumer c = new Consumer(w);
  7.         p.start();
  8.         c.start();
  9.     }
  10. }
  11. class Proudcer extends Thread {
  12.     Warehouse w;

  13.     Proudcer(Warehouse w) {
  14.         this.w = w;
  15.     }
  16.     @Override
  17.     public void run() {
  18.         for (int i = 1; i <= 10; i++) {
  19.             // 生产商品
  20.             w.put(i);
  21.             //该语句引起问题
  22.             System.out.println("Producer 生产 " + i);
  23.         }
  24.     }
  25. }

  26. class Consumer extends Thread {
  27.     Warehouse w;

  28.     Consumer(Warehouse w) {
  29.         this.w = w;
  30.     }

  31.     @Override
  32.     public void run() {
  33.         while (true) {
  34.             //该语句引起问题
  35.             System.out.println("Customer "+" 消费 "+ w.get());
  36.         }
  37.     }
  38. }
  39. class Warehouse {
  40.     private int value;
  41.     boolean bFull = false; //仓库是否有商品
  42.     // 生产商品
  43.     public  void put(int value) {
  44.         if (!this.bFull) { // 仓库中没有商品
  45.             this.value = value;
  46.             this.bFull = true;
  47.             this.notify(); // 通知消费者进行消费
  48.         }
  49.         try {
  50.             this.wait(); // 等待消费者消费商品
  51.         } catch (InterruptedException e) {
  52.             // TODO Auto-generated catch block
  53.             e.printStackTrace();
  54.         }

  55.     }
  56.     // 消费商品
  57.     public  int get() {
  58.         if (!this.bFull) { //仓库中没有商品
  59.             try {
  60.                 this.wait(); //等待生产者生产商品
  61.             } catch (InterruptedException e) {
  62.                 // TODO Auto-generated catch block
  63.                 e.printStackTrace();
  64.             }
  65.         }
  66.         this.bFull = false;
  67.         this.notify(); //通知生产者生产商品
  68.         return this.value;
  69.    
复制代码
请问上面的put和get方法为什么要枷锁,synchronized加在一个方法上,代表这个方法只能一个选择去运行吗,我感觉这边put只有生存者去调用,而get也只有消费者去调用,没有别的方法竞争啊,为什么要加synchronized,谢谢大神帮忙。
作者: "O_忆_O    时间: 2013-7-18 13:04
按照我的印象,毕老师写的代码是有两个生产者和两个消费者的,所以这样就存在安全问题了啊。另外,消费者和生产者要有一个先后过程的啊,加同一个锁就是为了让生产者生产完了,消费者再去消费。
作者: yangqing    时间: 2013-7-18 13:19
加锁不是为了解决程序的调用方法问题 ,put只有生存者调用 get只有消费者调用,这是没有问题的。加锁是为了解决线程的循序问题,cup选择线程是随机的,这样就会造成实际问题的混乱。。例如当cup在判断put方法还未结束时,切换到了 get方法 这样就有问题了 生产者还未生成结束 消费者就消费了。 加锁就是为了保证循序问题,
作者: 付龙    时间: 2013-7-18 20:47
为了解决安全问题,避免出现生产线程还没有生产完,就已经消费了这样的情况,加同步的目的是让生产线程执行完以后才可以才执行消费消费线程




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2