日期:2014-05-20  浏览次数:21213 次

[小白问题]关于java线程IPC
大家好,我是个java的小白玩家。。。。(这还用说么)
以下是在看传智播客教程的时候试验的一段代码,跟里面讲的那个代码一样,但是为什么它在我机器上运行的时候就不像在视频里运行的那么听话。。。[来自毕向东教程Day12-3]

class Res{//资源
 String name;
 String sex;
 boolean flag = false;//标记,后面会用到
}

class Input implements Runnable{//Thread-0
private Res r;

Input(Res r){
this.r = r;
}
public void run() {
int x = 0;
while(true){
synchronized(r){//锁是r
if(r.flag)//标记为真,就wait
try {
r.wait();
} catch (Exception e) {
}
//否则flag是假
if(x == 0){
r.name = "zhangsan";
r.sex = "male";
}
else{
r.name = "lisi";
r.sex = "female";
}
}
x = (x + 1) % 2;
r.flag = true;//将flag修改为真,
                        r.notify();//之后唤醒Thread-1
           //抛异常:Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
//at java.lang.Object.notify(Native Method)
//at cn.range.multithreadsnext.Input.run(A_Ipc.java:52)
}
}
}

class Output implements Runnable{
private Res r;
Output(Res r){
this.r = r;
}
public void run(){

while(true){
synchronized(r){//和Thread-0用的一个锁,因为下面是创建了一个
                                 //公共的Res r,在Input和Output两个类初始化的时候,传入
                                 //到其中的
if(!r.flag)//flag是false就wait
try {
r.wait();
} catch (Exception e) {
}

System.out.println(r.name + r.sex);
r.flag = false;//否则就在执行完之后,将flag修改为false
r.notify();//唤醒,注意:此处没(来得及)抛异常
}
}

}
}

public class A_Ipc {
public static void main(String[] args) {

Res r = new Res();

Input in = new Input(r);
Output out = new Output(r);

Thread tin = new Thread(in);
Thread tout = new Thread(out);

tin.start();
tout.start();
}

}


查API,如下:IllegalMonitorStateException - 如果当前的线程不是此对象监视器的所有者。
我在这段代码里所有的wait和notify方法都是通过同一个r调用的啊。。。
因此问题,茶饭不思,头痛欲裂,
跪求一大牛解救……以60分相报。。。= =
java IPC 进程同步

------解决方案--------------------
问题你这里调用时

r.notify();//之后唤醒Thread-1

没在同步块内,是无法保证调用线程在调用时拥有r对象锁的