本章多线程原理能够在操作系统学习记录中找到原理:咖啡ice的操作系统学习记录
Object类中wait和notify方法是建立在synchronized线程同步基础之上。
wait和notify不是线程对象的方法,是java任何一个java对象都有的方法,这是Object类自带的。不是通过线程对象调用。
wait()方法:让正在这个对象上活动的线程(当前线程)进入等待状态,无期限等待,直到被唤醒为止。
notify()方法:唤醒被wait方法进入等待状态的线程。
notifyAll()方法:唤醒某个对象上处于等待的所有线程。
生产者-消费者模式:
生产者:在一个池里边,生产满了就无法继续生产了。
? 生产的产品被消费者消费。
消费者:在一个池里边没有产品,就不能消费了。
? 消费生产者生产的产品。
使用wait和notify方法实现生产者-消费者模式
需求:
package studyThread;
import java.util.ArrayList;
import java.util.List;
//使用notify和wait方法实现生产者消费者模式
public class ThreadTest14 {
public static void main(String[] args) {
//创建一个仓库,共享的
List list = new ArrayList();
//创建两个线程对象
//生产者线程
Thread t1 = new Thread(new Producer(list));
//消费者线程
Thread t2 = new Thread(new Consumer(list));
//设置名称
t1.setName("生产者");
t2.setName("消费者");
//启动
t1.start();
t2.start();
}
}
//生产线程
class Producer implements Runnable{
//仓库
private List list;
public Producer(List list) {
this.list = list;
}
@Override
public void run() {
//一直生产
while (true){
//给仓库对象list加锁,
synchronized (list){
if(list.size()>0){
//大于0表示仓库已经有一个元素了
//当前线程进入等待状态
try {
//当前对象进入等待状态,并释放list集合的锁。
list.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
//程序能到这,说明仓库为空,可以生成
Object obj = new Object();
list.add(obj);
System.out.println(Thread.currentThread().getName() + "生产成功,生产了:" + obj);
//唤醒消费者进行消费
list.notifyAll();
}
}
}
}
//消费线程
class Consumer implements Runnable{
//仓库
private List list;
public Consumer(List list) {
this.list = list;
}
@Override
public void run() {
//一直消费
while (true){
synchronized (list){
if(list.size()==0){
//仓库已经空了
try {
list.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
//程序到这里证明仓库不为空,可以进行消费
Object obj = list.remove(0);
System.out.println(Thread.currentThread().getName() + "消费成功,消费掉" + obj);
//唤醒生产者进行生产
list.notifyAll();
}
}
}
}