黑马程序员技术交流社区
标题:
多线程——等待唤醒机制
[打印本页]
作者:
水蛭31
时间:
2015-6-19 11:01
标题:
多线程——等待唤醒机制
多线程——等待唤醒机制接着线程之间的通信, 这里有个问题, 同步了, 但是运行的话, 会执行一大片, 但是一般都是存一个,输出一个,
为什么会执行一大片?
一个线程可能一直拥有CPU的执行权;
如何解决?(参考代码)
这里可以用一个标记来标识(flag),当存一个完了之后, 就改变这个标识,当下次再执行时, 就不会再存了,
此时可以将这个线程1给冻结(sleep(时间(毫秒)),wait()),如果用sleep(),时间不确定, 所以就用wait(),当执行完了之后,
标识发生改变,再次执行时, 就处于冻结状态了,失去执行资格。
那什么时候恢复执行资格呢?
当另一个线程2进来将这个存的值,取走了, 就恢复执行资格,如何恢复?
当取走后, 标识再次发生改变,然后用notify(),唤醒线程1,此时如果这个线程2再次执行时, 由于没有了值, 那么就将线程2冻结,wait()。
这个过程就是线程间的等待唤醒机制。
代码如下:
class Res //共享资源的类
{
String name;
String sex;
boolean flag=false;
}
/*
等待的线程在哪里呢?
线程运行的时候, 内存中会建立一个叫做线程池的,等待线程都存放在线程池中,
当notify的时候, 都是唤醒的是线程池中的线程,当线程池中有许多的线程都在等待,
通常是唤醒第一被等待的线程, 按照顺序来叫醒
*/
class Input implements Runnable//需要用到一个资源,
{
private Res r;
Input(Res r){//传递过来一个资源类的对象
this.r=r;
}
public void run(){
int x=0;
while(true)
{
synchronized(r)//这里需要同步,
{
if(r.flag){
try{r.wait();}catch(Exception e){}//当为真时, 就等待, 不能再传值了,因为已经有值
}
if(x==0){
r.name="mike";
r.sex="man";
}
else{
r.name="小王";
r.sex="女女女女女女";
}
x=(x+1)%2;
r.flag=true;
r.notify();//在线程池中叫醒Output线程
}
}
}
}
class Output implements Runnable
{
private Res r;
Output(Res r){
this.r=r;
}
public void run(){
while(true)
{
synchronized(r){//这里也需要同步,并且锁需要是同一个锁。
if(!r.flag){
try{r.wait();}catch(Exception e){}
}
//Wait(), notify(), notifyAll(), 全部用在同步中,因为需要锁必须标识wait()线程所处的锁
System.out.println(r.name+"....."+r.sex);
r.flag=false;
r.notify();
}
}
}
}
class ThreadInputOutput
{
public static void main(String[] args)
{
Res r=new Res();
Input in=new Input(r);
Output out=new Output(r);
Thread t1=new Thread(in);
Thread t2=new Thread(out);
t1.start();
t2.start();
}
}
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2