您的位置:首页 > 其它

线程间的通信------------等待唤醒机制

2014-11-03 10:35 465 查看
线程间的通信

同步线程必须满足两个条件:

一:两个或两个以上的线程

二:都使用同一个锁对象

题目描述:

首先有一个资源池(Resource),输入线程(Input)不断往资源池内添加内容,输出线程(Output)不断往外输出内容

并且两个线程需要同步。需要的结果是,输入线程输入一个内容,然后立马输出线程读出一个内容。

第一次编写代码,不使用同步,也不是用等待唤醒机制

/**
*	线程间的通信:--------等待唤醒机制
*	题目描述:
*      首先由一个资源池(Resource),输入线程(Input)不断往资源池内添加内容,输出线程(Output)不断往外输出内容
*      并且两个线程需要同步
*
* */
class Resource{
String name;
String sex;
}

class Input implements Runnable{
boolean inputflag=false;
Resource r;
Input(Resource r){
this.r = r;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){

if(inputflag){
r.name = "mike";
r.sex = "man";
inputflag = false;
}
else {
r.name = "丽丽";
r.sex = "女";
inputflag = true;
}

}

}

}
class Output implements Runnable{
Resource r;
public Output(Resource r){
this.r = r;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
System.out.println(r.name+"-----"+r.sex);
}
}

}
public class ThreadSynchronized {

public static void main(String[] args) {
// TODO Auto-generated method stub
Resource r = new Resource();
Input in = new Input(r);
Output out = new Output(r);

Thread t1 = new Thread(in);
Thread t2 = new Thread(out);

t1.start();
t2.start();
}

}




出现上面情况,“mike------女”和“丽丽------man”明显感觉到很奇怪

解释原因:输入线程没有对输入完成的时候,输出线程就抢占了cpu,直接执行输出线程,因此才会有以上的奇怪现象

解决方案:加入线程同步,使输入线程和输出线程同步。对资源的操作时候就只有输入线程完成赋值后输出线程有能执行

加入线程同步块后的代码如下:

/*
线程间的通信:--------等待唤醒机制
题目描述:
首先由一个资源池(Resource),输入线程(Input)不断往资源池内添加内容,输出线程(Output)不断往外输出内容
并且两个线程需要同步

* */
class Resource{
String name;
String sex;
//boolean flag = false;  //该标记初始为false
}

class Input implements Runnable{
boolean inputflag=false;
Resource r;
Input(Resource r){
this.r = r;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
synchronized (r) {         //该地方必须加同步块
if(inputflag){
r.name = "mike";
r.sex = "man";
inputflag = false;
}
else {
r.name = "丽丽";
r.sex = "女";
inputflag = true;
}
}

}

}

}
class Output implements Runnable{
Resource r;
public Output(Resource r){
this.r = r;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
synchronized (r) {    //这个地方锁的对象一定要和上面同步块的锁对象一致,不一致就不满足同步条件
System.out.println(r.name+"-----"+r.sex);
}
}
}

}
public class ThreadSynchronized {

public static void main(String[] args) {
// TODO Auto-generated method stub
Resource r = new Resource();
Input in = new Input(r);
Output out = new Output(r);

Thread t1 = new Thread(in);
Thread t2 = new Thread(out);

t1.start();
t2.start();
}

}






但是问题又出现了,出现的全部是一样的结构,安装预期的应该是,一个“mike-----man”然后一个“丽丽------女”。但是为什么会出现这种情况呢?

这是由于输入线程获得cpu以后,多次赋值,等到输出线程获得cpu的时候就会一次输出好多的同样数据

解决方案:加入等待唤醒机制

/*
线程间的通信:--------等待唤醒机制
题目描述:
首先有一个资源池(Resource),输入线程(Input)不断往资源池内添加内容,输出线程(Output)不断往外输出内容
并且两个线程需要同步

* */
class Resource{
String name;
String sex;
boolean flag = false;  //该标记初始为false
}

class Input implements Runnable{
boolean inputflag=false;
Resource r;
Input(Resource r){
this.r = r;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
if(r.flag)   //如果标记位为false则让线程进入后面的同步块,如果为true则让该线程等待
try{ r.wait();}catch(Exception e){};
synchronized (r) {         //该地方必须加同步块
if(inputflag){
r.name = "mike";
r.sex = "man";
inputflag = false;
}
else {
r.name = "丽丽";
r.sex = "女";
inputflag = true;
}
r.flag = true;
//唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程
r.notify();  //即也就是唤醒output线程
}

}

}

}
class Output implements Runnable{
Resource r;
public Output(Resource r){
this.r = r;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
synchronized (r) {    //这个地方锁的对象一定要和上面同步块的锁对象一致,不一致就不满足同步条件
if(!r.flag)
try{ r.wait();}catch(Exception e){};
System.out.println(r.name+"-----"+r.sex);
r.flag = false;
r.notify();
}
}
}

}
public class ThreadSynchronized {

public static void main(String[] args) {
// TODO Auto-generated method stub
Resource r = new Resource();
Input in = new Input(r);
Output out = new Output(r);

Thread t1 = new Thread(in);
Thread t2 = new Thread(out);

t1.start();
t2.start();
}

}




最后可以看出,得出了我想要的结果
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: