您的位置:首页 > 编程语言 > Java开发

java多线程之间的通信

2009-12-02 08:37 405 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: