wait/notify是实现线程通信的基本操作。
wait:让本线程阻塞,并且释放当前锁。
notify:唤醒当前对象锁池等待的线程。
注意:
1、wait,notify必须是在多线程中进行使用,所以才会有通信。
2、一定要在synchronized中进行,而且必须要持有同一把锁。
代码详细解释说明:
结果分析:
输出结果如下:
生产者要执行notify....
小红-女
生产者over.................
生产者wait.....
消费者要执行notify...
消费者over................
消费者wait......
生产者要执行notify....
小明-男
生产者over.................
生产者wait.....
消费者要执行notify...
消费者over................
消费者wait......
生产者要执行notify....
小红-女
生产者over................
<1> 生产者或者消费者wait方法执行后,必然阻塞当前,然后去继续执行另一个线程,生产者wait后面必然是消费者执行的代码行,消费者wait后面必然是生产者的代码行。
<2>synchronized内的代码块一定会连续执行完毕
<3>线程同步说明:在多线程并发执行中,线程同步可以理解成线程排队执行,使用synchronized来实现,多个线程操作共享数据时,保证一个一个的去操作,而不是同时进行操作。
代码如下:
/**
*先定义一个类,作为生产和消费的对象
*/
class Res {
String name;
String sex;
public boolean flag = false;
}
/**
* 生产者
*/
class ProduceThread extends Thread {
public Res res;
int count = 0;
public ProduceThread(Res res) {
this.res = res;
}
@Override
public void run() {
while(true) {
synchronized(res) {
if(res.flag) {
try {
System.out.println("生产者wait.....");
res.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("生产者要执行notify....");
count++;
if(count%2==0) {
res.name = "小红";
res.sex = "女";
}else {
res.name = "小明";
res.sex = "男";
}
System.out.println(res.name+"-"+res.sex);
res.flag = true;
res.notify();
System.out.println("生产者over.................");
}
}
}
}
/**
* 消费者
*/
class ConsumeThread extends Thread {
public Res res;
public ConsumeThread(Res res) {
this.res = res;
}
@Override
public void run() {
while(true) {
synchronized(res) {
if(!res.flag) {
try {
System.out.println("消费者wait......");
res.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费者要执行notify...");
res.flag = false;
res.notify();
System.out.println("消费者over................");
}
}
}
}
public class ProduceConsume {
public static void main(String[] args) throws InterruptedException {
System.out.println("mian...............");
Thread.sleep(1000);
Res res = new Res();
ProduceThread p = new ProduceThread(res);
ConsumeThread c = new ConsumeThread(res);
p.start();
c.start();
}
}