关于Java线程等待唤醒机制的一个问题

sea000sea 2015-03-01 05:56:05
package cn.test.thread;



class Resource {
private String name;
private String sex;
boolean flag = false;
public synchronized void set(String name,String sex){
if(flag){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else {//这里加了个else之后,输出的结果不是想要的那种。去掉else,即可。可是为什么呢?请教大神!
this.name = name;
this.sex = sex;
this.notify();
this.flag = true;
}
}

public synchronized void out(){
if(!flag){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
System.out.println(name+"..."+sex);
this.notify();
this.flag = false;
}
}
}

/**
* 资源输入
* @author sea
*
*/
class Input implements Runnable{
Resource r;
public Input(Resource r){
this.r = r;
}
@Override
public void run() {
int num = 0;
while(true){
if(num == 0){
r.set("张三","男");
//System.out.println(Thread.currentThread().getName()+"资源输入");
}else{
r.set("lili", "female");
//System.out.println(Thread.currentThread().getName()+"资源输入");
}
num = ++num%2;
}
}
}

class Output implements Runnable{
Resource r ;
public Output(Resource r){
this.r = r;
}
@Override
public void run() {
while(true){
r.out();
}
}
}

public class InformationTest {

public static void main(String[] args) {
Resource r = new Resource();
Input ip = new Input(r);
Output op = new Output(r);

Thread t1 = new Thread(ip);
Thread t2 = new Thread(op);
t1.start();
t2.start();

}

}
...全文
211 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
sea000sea 2015-03-02
  • 打赏
  • 举报
回复
引用 3 楼 nmyangym 的回复:
我的看法,楼主参考: 问题就是当wait()结束后,程序从哪接着执行?正常情况下,wait()结束,应该执行else语句块里的内容,但你把它放在else里,它就不执行了,跳过了赋值语句。 另外,这种情况下最好用while,不用if,某些场合会出问题。
你说的很对。今天我看生产者和消费者的时候,理解了昨天的问题。确实是你说的那样,当一个线程从wait()中唤醒了后,是直接往下运行,这个时候如果我加了else的话,直接就从else上面跳过去了,虽然此刻flag=false,接着往下运行后此刻的值还是原来那个值,num的值转变了,结果还是之前的值,不是没变,而是跳过去了。所以,这里不能加else。
nmyangym 2015-03-02
  • 打赏
  • 举报
回复
我的看法,楼主参考: 问题就是当wait()结束后,程序从哪接着执行?正常情况下,wait()结束,应该执行else语句块里的内容,但你把它放在else里,它就不执行了,跳过了赋值语句。 另外,这种情况下最好用while,不用if,某些场合会出问题。
sea000sea 2015-03-01
  • 打赏
  • 举报
回复
引用 1 楼 cumtwyc 的回复:
boolean flag = false;改为volatile boolean flag = false;
问题依旧啊!
wyc_ 2015-03-01
  • 打赏
  • 举报
回复
boolean flag = false;改为volatile boolean flag = false;

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧