java多线程之间的通信

来源:互联网 发布:示剑网络 编辑:程序博客网 时间:2024/05/14 09:09

java多线程通信 收藏
转载请注明:来自http://blog.csdn.net/M_ChangGong/ 作者:张燕广

java多线程通信,模拟生产者-消费者关系。

第1种实现(该实现存在问题),具体代码如下:

 view plaincopy to clipboardprint?
package com.zhangyg.thread.mytest;  
 
/** 
 * 模拟生产者-消费者关系 
 * @author 张燕广 
 * 
 */ 
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();  
    }  
}  
 
/** 
 * 生产者 
 * @author 张燕广 
 * 
 */ 
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);  
        }  
    }  
}  
 
/** 
 * 消费者 
 * @author 张燕广 
 * 
 */ 
class Consumer extends Thread {  
    Warehouse w;  
 
    Consumer(Warehouse w) {  
        this.w = w;  
    }  
 
    @Override 
    public void run() {  
        while (true) {  
            //该语句引起问题  
            System.out.println("Customer "+" 消费 "+ w.get());  
        }  
    }  
}  
 
/** 
 * 仓库 
 * @author 张燕广 
 * 
 */ 
class Warehouse {  
    private int value;  
    boolean bFull = false; //仓库是否有商品  
    // 生产商品  
    public synchronized 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 synchronized 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;  
    }  

package com.zhangyg.thread.mytest;

/**
 * 模拟生产者-消费者关系
 * @author 张燕广
 *
 */
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();
 }
}

/**
 * 生产者
 * @author 张燕广
 *
 */
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);
  }
 }
}

/**
 * 消费者
 * @author 张燕广
 *
 */
class Consumer extends Thread {
 Warehouse w;

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

 @Override
 public void run() {
  while (true) {
   //该语句引起问题
   System.out.println("Customer "+" 消费 "+ w.get());
  }
 }
}

/**
 * 仓库
 * @author 张燕广
 *
 */
class Warehouse {
 private int value;
 boolean bFull = false; //仓库是否有商品
 // 生产商品
 public synchronized 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 synchronized 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都进行了同步操作,但是执行以上代码,打印的结果却是错误的。原因是Proudcer类中run方法中以下两行代码没有进行同步操作:

    w.put(i);
    //该语句引起问题
    System.out.println("Producer 生产 " + i);

   当执行完毕w.put(i);后CPU时间片完毕,这时候下面的打印语句还没有执行,所以就出问题了。

 第2种实现,修改第1种实现,解决其存在的问题,具体代码如下:

  view plaincopy to clipboardprint?
package com.zhangyg.thread.mytest1;  
 
/** 
 * 模拟生产者-消费者关系 
 * @author 张燕广 
 * 
 */ 
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();  
    }  
}  
 
/** 
 * 生产者 
 * @author 张燕广 
 * 
 */ 
class Proudcer extends Thread {  
    Warehouse w;  
 
    Proudcer(Warehouse w) {  
        this.w = w;  
    }  
 
    @Override 
    public void run() {  
        for (int i = 1; i <= 10; i++) {  
            // 生产商品  
            w.produce(i);  
        }  
    }  
}  
 
/** 
 * 消费者 
 * @author 张燕广 
 * 
 */ 
class Consumer extends Thread {  
    Warehouse w;  
 
    Consumer(Warehouse w) {  
        this.w = w;  
    }  
 
    @Override 
    public void run() {  
        while (true) {  
            w.consume();  
        }  
    }  
}  
 
/** 
 * 仓库 
 * @author 张燕广 
 * 
 */ 
class Warehouse {  
    private int value;  
    private boolean bFull = false; //仓库是否有商品  
    // 生产商品  
    public synchronized void produce(int newValue) {  
        if (!this.bFull) { // 仓库中没有商品  
            this.value = newValue;  
            System.out.println("Producer:生产 " + newValue);  
            this.bFull = true;  
            this.notify(); // 通知消费者进行消费  
        }  
        try {  
            this.wait(); // 等待消费者消费商品  
        } catch (InterruptedException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
 
    }  
 
    // 消费商品  
    public synchronized void consume() {  
        if (!this.bFull) { //仓库中没有商品  
            try {  
                this.wait(); //等待生产者生产商品  
            } catch (InterruptedException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
        this.bFull = false;  
        this.notify(); //通知生产者生产商品  
        System.out.println("Customer->消费 " + this.value);  
    }  

package com.zhangyg.thread.mytest1;

/**
 * 模拟生产者-消费者关系
 * @author 张燕广
 *
 */
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();
 }
}

/**
 * 生产者
 * @author 张燕广
 *
 */
class Proudcer extends Thread {
 Warehouse w;

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

 @Override
 public void run() {
  for (int i = 1; i <= 10; i++) {
   // 生产商品
   w.produce(i);
  }
 }
}

/**
 * 消费者
 * @author 张燕广
 *
 */
class Consumer extends Thread {
 Warehouse w;

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

 @Override
 public void run() {
  while (true) {
   w.consume();
  }
 }
}

/**
 * 仓库
 * @author 张燕广
 *
 */
class Warehouse {
 private int value;
 private boolean bFull = false; //仓库是否有商品
 // 生产商品
 public synchronized void produce(int newValue) {
  if (!this.bFull) { // 仓库中没有商品
   this.value = newValue;
   System.out.println("Producer:生产 " + newValue);
   this.bFull = true;
   this.notify(); // 通知消费者进行消费
  }
  try {
   this.wait(); // 等待消费者消费商品
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }

 // 消费商品
 public synchronized void consume() {
  if (!this.bFull) { //仓库中没有商品
   try {
    this.wait(); //等待生产者生产商品
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  this.bFull = false;
  this.notify(); //通知生产者生产商品
  System.out.println("Customer->消费 " + this.value);
 }
}

   该实现虽然没有什么问题,但是其设计并不合理。

第3种实现,完善第2种实现,具体代码如下:

view plaincopy to clipboardprint?
package com.zhangyg.thread.mytest2;  
 
/** 
 * 模拟生产者-消费者关系 
 * @author 张燕广 
 * 
 */ 
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();  
    }  
}  
 
/** 
 * 生产者 
 * @author 张燕广 
 * 
 */ 
class Proudcer extends Thread {  
    Warehouse w;  
 
    Proudcer(Warehouse w) {  
        this.w = w;  
    }  
 
    @Override 
    public void run() {  
        for (int i = 1; i <= 10; i++) {  
            // 生产商品  
            this.produce(i);  
        }  
    }  
      
    // 生产商品  
    public void produce(int value){  
        synchronized(w){  
            if (!w.isBFull()) { // 仓库中没有商品  
                w.setValue(value);  
                System.out.println("Producer:生产 " + value);  
                w.setBFull(true);  
                w.notify(); // 通知消费者进行消费  
            }  
            try {  
                w.wait(); // 等待消费者消费商品  
            } catch (InterruptedException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
    }  
}  
 
/** 
 * 消费者 
 * @author 张燕广 
 * 
 */ 
class Consumer extends Thread {  
    Warehouse w;  
 
    Consumer(Warehouse w) {  
        this.w = w;  
    }  
 
    @Override 
    public void run() {  
        while (true) {  
            this.consume();  
        }  
    }  
      
    // 消费商品  
    public void consume(){  
        synchronized(w){  
            if (!w.isBFull()) { //仓库中没有商品  
                try {  
                    w.wait(); //等待生产者生产商品  
                } catch (InterruptedException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
            }  
            w.setBFull(false);  
            w.notify(); //通知生产者生产商品  
            System.out.println("Customer->消费 " + w.getValue());  
        }  
    }  
}  
 
/** 
 * 仓库 
 * @author 张燕广 
 * 
 */ 
class Warehouse {  
    private int value;  
    private boolean bFull = false; //仓库是否有商品  
      
    public int getValue() {  
        return value;  
    }  
 
    public void setValue(int value) {  
        this.value = value;  
    }  
 
    public boolean isBFull() {  
        return bFull;  
    }  
 
    public void setBFull(boolean full) {  
        bFull = full;  
    }  


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/m_changgong/archive/2009/08/20/4466062.aspx