1.基于synchronzied底层,与wait、notifyAll实现
Object类提供的wait、notify方法,配合synchronized使用,操作更底层,可扩展性和可控制性小。
先来介绍一下wait()、notify()、notifyAll()方法:
- wait():Object类的方法,只能在同步方法或在同步代码块中使用;该方法会在wait()所在的代码处停止运行,直到被notify()唤醒;会交出CPU,会释放锁,线程从运行态 -> 阻塞态;
- notify():使停止的线程继续运行,只能在同步方法或在同步代码块中使用;退出同步代码块之后才会释放对象锁;如果有多个线程wait,挑出一个线程唤醒。
- notifyAll():唤醒所有等待的线程。
源码:
class Goods{
private String goodsName;
private int count;
//生产方法
public synchronized void set(String goodsName) throws InterruptedException {
while(this.count == 10){
//商品已经生产到最大数量了,先消费不生产
wait();
}
System.out.println(Thread.currentThread().getName());
//生产商品,一次多个
this.goodsName = goodsName;
this.count = count + 1;
Thread.sleep(1000);
System.out.println("生产" + toString());
notifyAll();
}
//消费方法
public synchronized void get() throws InterruptedException {
while(this.count == 0){
wait();
}
System.out.println(Thread.currentThread().getName());
this.count = count - 1;
Thread.sleep(1000);
System.out.println("消费" + toString());
notifyAll();
}
@Override
public String toString() {
return "Goods[goodsName="+goodsName+",count="+count+"]";
}
}
//生产者类
class Producer implements Runnable{
private Goods goods;
public Producer(Goods goods) {
super();
this.goods = goods;
}
@Override
public void run() {
while(true) {
try {
this.goods.set("iphone");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//消费者类
class Consumer implements Runnable{
private Goods goods;
public Consumer(Goods goods) {
super();
this.goods = goods;
}
@Override
public void run() {
while(true) {
try {
this.goods.get();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main{
public static void main(String[] args) throws InterruptedException {
Goods goods = new Goods();
Producer producer = new Producer(goods);
Consumer consumer = new Consumer(goods);
List<Thread> threadList = new ArrayList<>();
for(int i = 0; i<5; i++){
Thread producerThread = new Thread(producer);
producerThread.setName("生产者"+i);
threadList.add(producerThread);
}
for(int i = 0; i<5; i++){
Thread consumerThread = new Thread(consumer);
consumerThread.setName("消费者"+i);
threadList.add(consumerThread);
}
for(Thread thread:threadList){
thread.start();
}
}
}
2.在Condition机制下,与Lock体系配合实现
Condition机制下的生产消费者模型,与Lock体系配合使用,操作在语言层,可扩展性和可控制性好
await()、signalAll()方法
源码:
class Goods{
//商品名称
private String goodsName;
//当前商品数量
private int count;
//商品最大数量
private int maxCount;
public Goods(int maxCount) {
this.maxCount = maxCount;
}
private Lock lock = new ReentrantLock();
private Condition producer = lock.newCondition();
private Condition consumer = lock.newCondition();
//生产方法
public void setGoods(String goodsName){
lock.lock();
try {
while(this.count == maxCount){
//商品数量已经达到了上限,停止生产
producer.await();
}
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
this.goodsName = goodsName;
count++;
System.out.println("生产"+toString());
producer.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
//消费方法
public void getGoods(String goodsName){
lock.lock();
try {
while(this.count == 0){
//商品消费完了,停止消费
consumer.await();
}
System.out.println(Thread.currentThread().getName());
this.goodsName = goodsName;
count--;
System.out.println("消费"+toString());
consumer.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
@Override
public String toString() {
return "Goods[goodsName="+goodsName+",count="+count+"]";
}
}
//生产者类
class Producer implements Runnable{
private Goods goods;
public Producer(Goods goods) {
super();
this.goods = goods;
}
@Override
public void run() {
while(true){
goods.setGoods("iphone");
}
}
}
//消费者类
class Consumer implements Runnable{
private Goods goods;
public Consumer(Goods goods) {
super();
this.goods = goods;
}
@Override
public void run() {
while(true){
goods.getGoods("iphone");
}
}
}
public class Main {
public static void main(String[] args) {
Goods goods = new Goods(10);
Producer producer = new Producer(goods);
Consumer consumer = new Consumer(goods);
//队列是为了方便启动多个线程
List<Thread> threadList = new ArrayList<>();
for(int i = 0; i<5; i++){
Thread producerThread = new Thread(producer);
producerThread.setName("生产者"+i);
threadList.add(producerThread);
}
for(int i = 0; i<5; i++){
Thread consumerThread = new Thread(consumer);
consumerThread.setName("消费者"+i);
threadList.add(consumerThread);
}
for(Thread thread:threadList){
thread.start();
}
}
}