下面是一个生产者消费者实例。wait使得当前执行的线程进入某个对象的休息池,notify唤醒某个对象休息池中的某个线程,使其进入某个对象的等待池,等到该线程重新获得锁定,就会继续执行之前wait后面的代码。
public class ThreadDemo2 {
public static void main(String args[]){
Q p=new Q();
new Thread(new Producer(p)).start();
new Thread(new Consumer(p)).start();
}
}
class Producer implements Runnable{
private Q p;
private int i=0;
public Producer( Q p){
this.p=p;
}
public void run(){
while(true){
if(i==0){
p.put("zhangsan","male");
} else{
p.put("lisi","female");
}
i=(i+1)%2;
}
}
}
class Consumer implements Runnable{
private Q p;
public Consumer( Q p){
this.p=p;
}
public void run (){
while(true){
p.get();
}
}
}
class Q{
private String name="";
private String sex="";
private Boolean isfull=false;
public synchronized void put (String a,String b){
if(isfull){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
name=a;
sex=b;
System.out.println("produces:"+name);
System.out.println("produces:"+sex);
isfull=true;
notify();
}
public synchronized void get(){
if(!isfull){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
System.out.println("consumes:"+name);
System.out.println("consumes:"+sex);
isfull=false;
notify();
}
}
其实,不用标志位isfull也可以,如下:
public class ThreadDemo2 {
public static void main(String args[]){
Q p=new Q();
new Thread(new Producer(p)).start();
new Thread(new Consumer(p)).start();
}
}
class Producer implements Runnable{
private Q p;
private int i=0;
public Producer( Q p){
this.p=p;
}
public void run(){
while(true){
if(i==0){
p.put("zhangsan","male");
} else{
p.put("lisi","female");
}
i=(i+1)%2;
}
}
}
class Consumer implements Runnable{
private Q p;
public Consumer( Q p){
this.p=p;
}
public void run (){
while(true){
p.get();
}
}
}
class Q{
private String name="";
private String sex="";
public synchronized void put (String a,String b){
name=a;
sex=b;
System.out.println("produces:"+name);
System.out.println("produces:"+sex);
notify();
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
public synchronized void get(){
System.out.println("consumes:"+name);
System.out.println("consumes:"+sex);
notify();
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}
首先notify休息池中的线程,然后将当前线程放入休息池