黑马程序员技术交流社区
标题:
多线程唤醒问题
[打印本页]
作者:
关山明月
时间:
2015-2-2 20:28
标题:
多线程唤醒问题
本帖最后由 关山明月 于 2015-3-4 11:23 编辑
昨晚上看毕老师的视频,讲到同步、 wait() 和notify() 方法,具体代码如下:
class Res //资源
{
private String name;
private String sex;
private boolean flag=false;
public synchronized void set(String name,String sex)
{
if(flag)
{
try{this.wait();} catch(Exception e){} //线程等待
}
this.name=name;
this.sex=sex;
flag=true;
this.notify(); //唤醒线程池中的在等待线程
}
public synchronized void out()
{
if(!flag)
{
try{this.wait();} catch(Exception e){} //线程等待
}
System.out.println(this.name+" "+this.sex);
flag=false;
this.notify();
}
}
class Input implements Runnable //输入线程
{
private Res r;
Input(Res r)
{
this.r=r;
}
public void run()
{
int x=0;
while(true)
{
if(x==0)
{
r.set("张三","男");
}
else
{
r.set("lisi","woman");
}
x=(x+1)%2;
}
}
}
class Output implements Runnable //输出线程
{
private Res r;
Output(Res r)
{
this.r=r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
class MulThreadDemo2
{
public static void main(String[] args)
{
Res r=new Res();
new Thread(new Input(r)).start();
new Thread(new Output(r)).start();
}
}
复制代码
wait()是线程等待,notify()是唤醒线程池中的在等待线程,当第一次线程运行代码的时候,我自己创建的两个线程中另一个没有获得CUP执行权的线程就已经在线程池里处于等待状态吗?还没有接触到线程池,不知道自己创建的多个线程刚开始是什么状态的。。。。。如果刚开始不是在线程池里处于等待状态的话,那当第一个线程执行上面代码中的set()方法时,第一次运行notify()方法时唤醒的是哪个呢?
作者:
kenfine
时间:
2015-2-2 23:08
唤醒的是在此对象监视器上等待的单个线程。,有一个notifyAll()则是唤醒全部进程。线程池,在方老师的深入JAVA课程中有讲过,你就当是一个数组,里面的数组元素都是一条条线程就好。notify唤醒线程后,线程是可执行的,但不一定运行,要等待CPU调用
作者:
coolmiao13
时间:
2015-2-3 00:19
第一次线程运行是创建线程的时候,这个时候没有运行到wait,也就是说没有冻结状态。当时是有两个线程的一个是main,另一个就是新建立的线程,谁得到cpu执行权,谁继续运行,那么没有得到执行权的线程处于等待状态,注意不是冻结状态。这个时候两个线程会交替执行。当一个线程遇到wait的时候会进入冻结状态,之后必须使用notify来唤醒他还可以使其正常工作。当没有冻结线程的时候notify应该没有工作。以上我的理解。有不对的地方希望高手指教。
作者:
Ender亮
时间:
2015-2-3 08:46
本帖最后由 Ender亮 于 2015-2-3 08:54 编辑
代码中一共有三个线程:主线程,输入线程,输出线程。
主线程运行,会逐一开启二个线程,此时它们没有得到cpu运行权。主线程终止或cpu的原因,会让输入或输出线程得到cpu执行权。
如果是输入线程先得到CPU执行权,则最终会调用到07行的函数(并会循环这个函数),运行里面的代码:此时flag是flase,if语句不执行,继续向下,名字性别被赋值,flag被改为true;运行notify(),
因为没有被wait()的线程,所以没有需要被唤醒的,
然后在循环进入这个函数,此时flag为true,则这个线程调用wait()方法,睡眠了,释放了监视器(也就是视频中说的锁),等待被唤醒。
如果是输出线程先得到cpu执行权,同理,会最终调用19行的函数(并循环这个函数),运行里面代码:此时flag是flase,if语句执行,调用wait()方法,此线程被睡眠,释放了监视器(也就是视频中说的锁),等待被唤醒。
wait(),notify()方法是和对象相关联的,因为这个对象,所以他们联系到了一起,被放在了同一个线程池中(这个我自己的理解,我也不很清楚线程池,不用管线程池,只知道同一对象将他们联系到了一起就行),
notify()会开启在线程池中的第一个由wait()睡眠的线程(先由wait()睡眠的就排前面),如果没有就不用开启。
作者:
关山明月
时间:
2015-2-3 19:22
Ender亮 发表于 2015-2-3 08:46
代码中一共有三个线程:主线程,输入线程,输出线程。
主线程运行,会逐一开启二个线程,此时它们没有得到c ...
谢谢,标红色部分就是我需要的,弄明白了 :handshake
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2