Built-in locks and Lock locks implement producer-consumer models
Synchronized implementation code:
synchornized must be used in synchronization blocks or synchronization methods.
import java.util.ArrayList; import java.util.List; class Goods{ private String goodsName; private Integer count=0; //Maximum inventory private Integer full; public Goods(Integer full) { this.full = full; } public synchronized void setGoods(String goodsName){ //When the production is equal to the maximum stock, the producer waits while (this.count==this.full){ System.out.println("There's a lot of stock left. Buy it quickly."); try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.goodsName=goodsName; this.count++; System.out.println(Thread.currentThread().getName()+"production"+this.toString()); //Wake up Consumers to Buy notifyAll(); } public synchronized void getGoods(){ //Consumers wait when the number of products equals zero while (this.count==0){ System.out.println("In production, wait a minute."); try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.count--; System.out.println(Thread.currentThread().getName()+"consumption"+this.toString()); //Awakening Producer Production notifyAll(); } @Override public String toString() { return "Goods{" + "goodsName='" + goodsName + '\'' + ", count=" + count + '}'; } } //Producer class class Productor implements Runnable{ private Goods goods; public Productor(Goods goods) { this.goods = goods; } @Override public void run() { while (true){ this.goods.setGoods("mac"); } } } //Consumer class class Customer implements Runnable{ private Goods goods; public Customer(Goods goods) { this.goods = goods; } @Override public void run() { while (true){ this.goods.getGoods(); } } } public class Test{ public static void main(String[] args) { Goods goods=new Goods(20); Productor productor=new Productor(goods); Customer customer=new Customer(goods); List<Thread> list=new ArrayList<>(); for(int i=0;i<5;i++){ Thread thread=new Thread(productor,"Producer"+i); list.add(thread); } for(int i=0;i<10;i++){ Thread thread=new Thread(customer,"Consumer"+i); list.add(thread); } for(Thread thread:list){ thread.start(); } } }
Lock lock implements producer and consumer model source code:
lock locks must be matched with try.. Final use (must be unlocked in the final block of code).
import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class Goods{ private String goodsName; private Integer count=0; private Integer full; //Get the lock object private Lock lock=new ReentrantLock(); //Get the producer waiting queue object private Condition productorCondition=lock.newCondition(); //Get the consumer waiting queue object private Condition customerCondition=lock.newCondition(); public Goods(Integer full) { this.full = full; } public void setGoods(String goodsName){ try{ lock.lock();//Lock up while (this.count==this.full){ System.out.println("There's a lot of stock. Come and buy it."); try { productorCondition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } this.goodsName=goodsName; this.count++; System.out.println(Thread.currentThread().getName()+"production"+this.toString()); customerCondition.signalAll(); }finally { lock.unlock();//Unlock } } public void getGoods(){ try { lock.lock(); while (this.count==0){ System.out.println("Goods are in production. Wait a minute."); try { customerCondition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } this.count--; System.out.println(Thread.currentThread().getName()+"consumption"+this.toString()); productorCondition.signalAll(); }finally { lock.unlock(); } } @Override public String toString() { return "Goods{" + "goodsName='" + goodsName + '\'' + ", count=" + count + '}'; } } class Productor implements Runnable{ private Goods goods; public Productor(Goods goods) { this.goods = goods; } @Override public void run() { while (true){ this.goods.setGoods("mac"); } } } class Customer implements Runnable{ private Goods goods; public Customer(Goods goods) { this.goods = goods; } @Override public void run() { while (true){ this.goods.getGoods(); } } } public class Test{ public static void main(String[] args) { Goods goods=new Goods(20); Productor productor=new Productor(goods); Customer customer=new Customer(goods); List<Thread> list=new ArrayList<>(); for(int i=0;i<5;i++){ Thread thread=new Thread(productor,"Producer"+i); list.add(thread); } for(int i=0;i<10;i++){ Thread thread=new Thread(customer,"Consumer"+i); list.add(thread); } for(Thread thread:list){ thread.start(); } } }
Built-in locks and Lock locks are implemented to compare producer and consumer models:
It is suggested to use Lock lock, because Lock lock can realize multiple waiting queues (one queue can store the same property threads, which is easy to manage), non-response interruption and setting deadline function, and Lock lock has manual locking and unlocking process, which is more convenient to use.