线程等待,线程唤醒
- “锁“中的主要方法
- wait(): 让线程处于冻结状态,被wait的线程会被存储到线程池中。
- notify():唤醒线程池中一个线程(任意),没有顺序。
- notifyAll():唤醒线程池中的所有线程。
因为synchronized模块的监视器是任意对象,所以这些方法定义在Object中
注意:
**这些方法都必须定义在同步中。因为这些方法是用于操作线程状态的方法。
必须要明确到底操作的是哪个锁上的线程。也就是哪个锁调用了方法,那么这个锁里面的进城做出相应的动作**
- 所谓的监听器即”锁”,这个锁不仅可以锁住进程,还可以监视进程,每个监听器都有进程缓冲池,
相应的监听器调用wait方法只能作用于自己缓冲池中的进程
所以一一定要保证是同一个锁
示例:
class Person
{
private String name;
private String country;
private boolean flag = false;//默认数据为空
//封装写数据方法
synchronized void setData(String name,String country)
{
if(flag)//里面没有数据,将取数据进程等待
try{this.wait();}catch (InterruptedException ex){}//因为wait方法有抛出异常(wait继承于Object)
this.name = name;
this.country = country;
flag = true;//数据已经写入,转换标识
this.notify();//唤醒取数据进程
}
//封装取数据方法
synchronized void getData( )
{
if(!flag)//不为空,则写数据进程等待
try{this.wait();}catch (InterruptedException ex){}
System.out.println("name: "+name+"---country: "+country);
flag = false;
this.notify();
}
}
//定义写数据线程任务
class Input implements Runnable
{
Person p;
Input(Person p)
{
this.p = p;
}
public void run()
{
int i = 0;
while(true)
{
if(i == 0)//为了模拟多个数据输出
p.setData("女娲","中国");
else
p.setData("God","American");
i=(i+1)%2;
}
}
}
//定义取数据进程
class Output implements Runnable
{
Person p;
Output(Person p)
{
this.p = p;
}
public void run()
{
while(true)
{
p.getData();
}
}
}
class ThreadWait
{
public static void main(String[] args)
{
//创建数据对象
Person p = new Person();
//创建线程任务
Input in = new Input(p);
Output out = new Output(p);
//创建线程
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
//开始
t1.start();
t2.start();
}
}
这个就是生产者和消费者模式的”前身“