Java是通过Object 类的wait() notify() notifyAll() 这几个方法实现线程间通信的。
wait():通知该线程进入睡眠状态,直到其他线程进入并调用notify()或notifyAll()为止。在当前线程睡眠之前,该线程会释放所占有的“锁标志”,即其占有的synchronized标识的代码块可被其他线程使用。
notify():唤醒在该同步代码块中第一个调用wait()的线程。这类似排队买票,一个人买完之后,后面的人才可以买。
notifyAll():唤醒该同步代码块中所有调用wait的所有线程,具有最高优先级的线程首先被唤醒并执行。
范例:
下Person类中定义一个新的成员变量bFull来表示数据存储的空间状态。当Consumer线程取走数据后,bFull值为false,当Producer线程放入数据后,bFull值为true。只有bFull为true时,Consumer线程才能取走数据,否则就必须等待Producer线程放入新的数据后的通知;反之,只有bFull为false时,Producer才能放入数据,否则就必须等待Consumer线程取走数据后的通知。
package 多线程基础;
public class ThreadCommunction_2 {
public static void main(String[] args)
{
Persons p=new Persons();
new Thread(new Producers(p)).start();
new Thread(new Consumers(p)).start();
}
}
class Producers implements Runnable
{
Persons p=null;
public Producers (Persons p)
{
this.p=p;
}
public void run()
{
for(int i=0;i<10;i++)
{
if(i%2==0)
{
p.set("张三", "男");
}
else
{
p.set("李四", "女");
}
}
}
}
class Consumers implements Runnable
{
Persons q=null;
public Consumers(Persons q)
{
this.q=q;
}
public void run()
{
for(int i=0;i<10;i++)
{
q.get();
}
}
}
class Persons
{
private boolean bFull=false; //false:没有产品,true:有产品
private String name;
private String sex;
public synchronized void set(String name,String sex)
{
if(bFull)
{
try {
wait(); //后来的线程要等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name=name;
this.sex=sex;
bFull=true;
notify();
}
public synchronized void get()
{
if(!bFull)
{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(this.name+"------>"+this.sex);
bFull=false;
notify();
}
}
输出:
张三------>男
李四------>女
张三------>男
李四------>女
张三------>男
李四------>女
张三------>男
李四------>女
张三------>男
李四------>女