Java线程之间的通信
线程之间的通信:wait(),notify(),notifyAll()
wait()——>让线程进入阻塞状态,暂停执行。一直阻塞
notify()——>唤醒线程,wait()住的线程,被唤醒。如果多个线程wait()了,唤醒其中的一个。
notifyAll()——>唤醒所有。
语法要求:必须在同步中,由同步的锁对象来调用。否则java.lang.IllegalMonitorStateException异常。
生产者(线程t1)负责生产产品,存入容器中(固定容量),消费者(线程t2)从容器中获取产品消费掉。 容器: 生产者:持有资源,生产产品,存入容器中 消费者:持有资源,消费掉产品。 容器满了:最多装8个鸡蛋 生产者:持有资源,暂停执行——直到容器还能继续装。 锁对象.wait()——>会让线程进入阻塞状态。暂停执行。notify(),notifyAll() 消费者:持有资源,直接消费。。 容器空了:最少0个。 生产者:持有资源,生产,存入。。 消费者:持有资源,暂停执行——直到容器中有产品 锁对象.wait()——>会让线程进入阻塞状态。暂停执行。notify(),notifyAll()

1、产品类:Egg()-->id 2、产生者:线程 cpu执行,run()-->生产鸡蛋,装入容器 3、消费者:线程 cpu执行,run()-->从容器中获取鸡蛋,吃掉(打印。。)
容器对象:
Class实现容器
数组: Egg[] arr = new Egg[8];
集合:栈,后进先出
同步的代码:
wait()和sleep()方法的区别:
-
出处不同:
-
sleep()方法是Thread类中定义的。
-
wait()方法是Object类中定义的。
-
-
解除阻塞的方式不同
-
sleep()是时间到,自己醒。
-
wait()方法等待被唤醒:notify(),或者是notifyAll()
-
-
对锁资源的释放情况
-
sleep(),不释放,抱着不撒手
-
wait(),释放
-

package com.qf.demo03;
import java.util.LinkedList;
//step1:产品类:Egg,ManTou,Computer,Bread。。。
class Egg {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Egg() {
super();
}
public Egg(int id) {
super();
this.id = id;
}
@Override
public String toString() {
return "Egg [id=" + id + "]";
}
}
// step2:生产者线程:代表母鸡,下蛋
class Producer implements Runnable {
// step5:通过构造方法,获取容器
private LinkedList<Egg> list;
private int id = 1;
public Producer(LinkedList<Egg> list) {
this.list = list;
}
@Override
public void run() {
// 母鸡下蛋,装容器
while (true) {
//t1
synchronized (list) {//t1
while(list.size() == 8){
System.out.println("容器满了,不能再装了,母鸡应该等待。。。");
try {
list.wait();//正在访问的list锁对象的线程,处于了等待状态,同时释放了锁对象。。
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 1.生产鸡蛋
Egg egg = new Egg(id++);//1,2
try {
Thread.sleep((int) (Math.random() * 1000));
// Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 2.存入容器
list.push(egg);//1个,2个
System.out.println(Thread.currentThread().getName() + ",母鸡下蛋:" + egg.getId());
list.notify();//唤醒消费者线程——>如果没有线程处于wait(),那么这就是空唤醒
}
}
}
}
// step3:消费者线程:代表吃货,吃鸡蛋
class Customer implements Runnable {
// step5:通过构造方法,让Customer类,获取这个容器
private LinkedList<Egg> list;
public Customer(LinkedList<Egg> list) {
this.list = list;
}
@Override
public void run() {
while (true) {
//t2
synchronized (list) {//this
while(list.size() == 0){
System.out.println("容器空的,不能吃了,吃货应该等待。。");
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 消费鸡蛋
Egg egg = list.pop();//8
try {
Thread.sleep((int) (Math.random() * 1000));
// Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\t" + Thread.currentThread().getName() + ",消费了鸡蛋:" + egg.getId());// 8,7
list.notify();//唤醒线程,唤醒刚刚因为list调用wait(),所处于等待的线程--->母鸡
}
}
}
}
public class Test5ProducerAndCustomer {
public static void main(String[] args) {
/*
* 模拟生产者和消费者
*/
// step4:先创建一个容器
LinkedList<Egg> list = new LinkedList<>();
// 传入到生产者和消费者:
Producer p = new Producer(list);
Customer c = new Customer(list);
Thread t1 = new Thread(p, "母鸡");
Thread t2 = new Thread(c, "吃货");
t1.start();
t2.start();
}
}

浙公网安备 33010602011771号