Object类中的wait和notify方法
-
锁池:
假设线程A已经拥有了某个对象(不是类)的锁,而其它线程B,C想要调用这个对象的某个synchronized方法(或者代码块)之前 必须获得该对象锁的拥有权,而恰巧该对象的锁目前正被A所占有,此时B,C线程就会被阻塞,进入一个地方去等待锁的释放,这个地方就是该对象的锁池
-
等待池
假设A线程调用了某个对象的wait方法,线程A就会释放该对象的锁,同时线程A就进入到了该对象的等待池中,进入等待池中的线程不会去竞争该对象的锁
-
wait() 让正在该对象上活动的线程进入等待状态,无限期等待,直到被唤醒为止。wait()方法的调用,会让正在该对象的当前线程进入等待状态
-
notify()方法作用
只会随机选取一个 处于等待池中 的线程进入 锁池 去竞争获取锁的机会
-
notifyAll():会让所有处于等待池的线程全部进入锁池去竞争获取锁的机会
生产者模式和消费者模式
package com.itguo.thread;
import java.util.ArrayList;
import java.util.List;
/**
* 生产者消费者
* 生产者与消费者之间均衡的状态
* 使用的技术:wait、notify
* 这两个方法只有在多线程同步的情况下才能使用
* 需求
* 生产者只要生产出了一个产品,就要消费者消费
* @author ShuaiGUO
*/
public class WaitDemo01 {
public static void main(String[] args) {
//创建仓库对象(共享对象)
House house = new House(new ArrayList());
//创建生产者线程
Producter producter = new Producter(house);
//创建消费者线程
Customer customer = new Customer(house);
//设置线程名字
producter.setName("生产者");
customer.setName("消费者");
//启动线程
producter.start();
customer.start();
}
}
/**
* 仓库类
*/
class House{
private List list;
public House(List list) {
this.list = list;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
}
/**
* 创建生产者类
*/
class Producter extends Thread{
private House house;
public Producter(House house) {
this.house = house;
}
@Override
public void run() {
//模拟一直生产
while (true){
synchronized (this.house){
if (this.house.getList().size()>0){
try {
//让当前线程处于等待状态,因为仓库有东西,所以不需要生产了,但同时消费者线程也被wait了
this.house.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//仓库中没有产品,生产者需要正常生产
this.house.getList().add(new Object());
//唤醒消费者消费
this.house.notifyAll();
System.out.println(this.getName()+"生产了一个产品,产品对象为"+this.house.getList().get(0));
try {
//睡眠1秒
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 创建消费者类
*/
class Customer extends Thread{
private House house;
public Customer(House house) {
this.house = house;
}
@Override
public void run() {
//模拟一直消费
while (true){
synchronized (this.house){
if (this.house.getList().size()==0){
try {
//当仓库中没有产品了,消费者线程就处于等待状态
this.house.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//仓库中有产品,消费者可以正常消费,使用remove模拟消费
Object remove = this.house.getList().remove(0);
System.out.println(this.getName()+"消费了一个产品,产品对象为"+remove);
try {
//睡眠1秒
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//唤醒生产者生产
this.house.notifyAll();
}
}
}
}