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

Java多线程㈣—①线程间通讯(生产者及消费者)

2015-02-12 16:19 483 查看
在线程操作中有一个经典的案例程序,即生产者和消费者问题,生产者不断生产,消费者不断取走生产者生产的产品。

假设:有两个线程,一个线程负责生产产品,一个线程负责消费产品。其中产品是两个线程处理的同一资源。由于线程的不确定性,所以会存在一下两点问题。

1、假设生产者线程向数据存储空间添加了资源的Husband,还没有加入该资源的Wife,程序就切换到了消费者线程,消费者线程将把资源的Husband和上一个信息的Wife联系到一起。

2、生产者放入了若干次的数据,消费者才开始取数据,或者是,消费者取完一个数据后,还没等到生产者放入新的数据,又重复取出已取过的数据。

程序的基本实现:

/*
线程间通讯:
多个线程在处理同一资源,但是任务却不同。
*/

//资源
class Resource{
private String husband;
private String wife;

public void setHusband(String husband){
this.husband = husband;
}
public String getHusband(){
return husband;
}

public void setWife(String wife){
this.wife = wife;
}
public String getWife(){
return wife;
}
}

//生产
class Producer implements Runnable{
private boolean flag = true;
private Resource r;
public Producer (Resource r){
this.r = r;
}
public void  run(){
while(true){
if(flag){
r.setHusband("郭靖");
r.setWife("黄蓉");
flag = false;
}else{
r.setHusband("董永");
r.setWife("七仙女");
flag = true;
}
}
}
}

//消费
class Consumer implements Runnable{
private Resource r;
public Consumer (Resource r){
this.r = r;
}
public void run(){
while(true){
System.out.println(r.getHusband()+"----------------"+r.getWife());
}
}
}

public class ThreadCommunication{
public static void main(String[] args){
//创建资源。
Resource r = new Resource();
//创建任务。
Producer p = new Producer (r);
Consumer c = new Consumer (r);
//创建线程,执行路径。
Thread t1 = new Thread(p);
Thread t2 = new Thread(c);
//开启线程
t1.start();
t2.start();
}
}




问题解决一:加入同步代码块:

class Resource{
private String husband;
private String wife;

public synchronized void set(String husband,String wife){
this.husband = husband;
this.wife = wife;
}
public synchronized Void get(){
System.out.println(husband+"----------------"+wife);
}
}

//生产
class Producer implements Runnable{
private boolean flag = true;
private Resource r;
public Producer (Resource r){
this.r = r;
}
public void  run(){
while(true){
if(flag){
r.set("郭靖","黄蓉");
flag = false;
}else{
r.set("董永","七仙女");
flag = true;
}
}
}
}

//消费
class Consumer implements Runnable{
private Resource r;
public Consumer (Resource r){
this.r = r;
}
public void run(){
while(true){
r.get();
}
}
}

public class ThreadCommunication2{
public static void main(String[] args){
//创建资源。
Resource r = new Resource();
//创建任务。
Producer p = new Producer (r);
Consumer c = new Consumer (r);
//创建线程,执行路径。
Thread t1 = new Thread(p);
Thread t2 = new Thread(c);
//开启线程
t1.start();
t2.start();
}
}




从程序的运行结果中可以发现,信息错乱的问题已经解决了,但是依然存在重复读取的问题,既然有重复读取,则肯定会有重复设置的问题,那么对于这样的问题该如何解决呢?

此时,就需要使用 Object类中的方法了(wait、notify、notifyAll)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐