There are three ways to implement, see the code comments for details:
package beijing.lele; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ProduceConsumeMoreThread { /** * Implemented using Lock + Condition class * In notifyAll using the first method, since notifyAll wakes up both its own and the opposite thread, the optimization is to wake up only the opposite process * */ public static void main(String[] args) { //Resources source =new Resources(); Use notifyAll to achieve multi-production and multi-consumption //ResourcesCondition source =new ResourcesCondition(); Use Lock Condition method ResourcesConditionMore rource =new ResourcesConditionMore(); // Use the improved Lock Condition method ProductorMore pro = new ProductorMore(rource); ConsumerMore con = new ConsumerMore (rource); Thread t1 =new Thread(pro,"张大厨"); Thread t2 =new Thread(pro,"Chef Li");//Multiple producers Thread t3 =new Thread(con,"学生甲"); Thread t4 =new Thread(con,"Student B");//Multiple consumers t1.start(); t2.start(); t3.start(); t4.start(); System.out.println("Hello World!"); } } class ConsumerMore implements Runnable { private Resources res; private ResourcesCondition res1; private ResourcesConditionMore res2; ConsumerMore(Resources res){ this.res =res; } ConsumerMore(ResourcesCondition res1){ this.res1 =res1; } ConsumerMore(ResourcesConditionMore res){ this.res2 =res; } public void run(){ while(true){ //res.out(); //res1.out(); res2.out(); } } } class ProductorMore implements Runnable { private Resources res; private ResourcesCondition res1 ; ResourcesConditionMore res2; ProductorMore(Resources res){ this.res =res; } ProductorMore(ResourcesCondition res){ this.res1 =res; } ProductorMore(ResourcesConditionMore res){ this.res2 =res; } public void run(){ while(true){ //res.set("++Commodity++"); //res1.set("++Commodity++"); res2.set("++商品++"); } } } /** This is the result of this version of the run, you can see that even in the consumption time Chef Zhang Producer++ Commodities++--1 Student A....Consumer....++Commodity++--1 Chef Zhang Producer++ Commodities++--2 Student A....Consumer....++Commodity++--2 Chef Zhang Producer++ Commodities++--3 Student A....Consumer....++Commodity++--3 Chef Zhang Producer++ Commodities++--4 Student B....Consumer....++Commodity++--4 Chef Zhang Producer++ Commodities++--5 Student B....Consumer....++Commodity++--5 Chef Zhang Producer++ Commodities++--6 Student B....Consumer....++Commodity++--6 Chef Zhang Producer++ Commodities++--7 Student B....Consumer....++Commodity++--7 Chef Zhang Producer++ Commodities++--8 Student B....Consumer....++Commodity++--8 Chef Zhang Producer++ Commodities++--9 Student B....Consumer....++Commodity++--9 Chef Zhang Producer++ Commodities++--10 Student B....Consumer....++Commodity++--10 Chef Zhang Producer++ Commodities++--11 Student A....Consumer....++Commodity++--11 Chef Zhang Producer++ Commodities++--12 Student A....Consumer....++Commodity++--12 Chef Lee Producer++ Commodities++--13 Student A....Consumer....++Commodity++--13 Chef Lee Producer++ Commodities++--14 Student A....Consumer....++Commodity++--14 * @author Administrator * */ class ResourcesCondition { private String name; private int count =1; private boolean flag =false; private Lock lock = new ReentrantLock(); // replace synchronized and provide more powerful functions private Condition condition = lock.newCondition(); public void set(String name) { lock.lock(); try { while(flag) { condition.await(); } Thread.sleep(200); this.name = name+"--"+count++; System.out.println(Thread.currentThread().getName()+"生产者"+this.name); flag = true; condition.signalAll(); // wake up } catch (InterruptedException e1) { e1.printStackTrace(); }finally { lock.unlock(); } } public synchronized void out() { lock.lock(); try{ //1) Loop judgment while(!flag){ condition.await(); } Thread.sleep(600); System.out.println(Thread.currentThread().getName()+" ....消费者...."+this.name); flag =false; condition.signalAll(); } catch (InterruptedException e) { e.printStackTrace (); }// Simulate consumption time finally { lock.unlock(); } } } class ResourcesConditionMore { private String name; private int count =1; private boolean flag =false; private Lock lock = new ReentrantLock(); private Condition condition_pro = lock.newCondition();// Use Lock to create the producer's condition object private Condition condition_consume = lock.newCondition();// Use Lock to create a consumer's condition object public void set(String name) { lock.lock(); try { while(flag) { condition_pro.await(); } Thread.sleep(200); this.name = name+"--"+count++; System.out.println(Thread.currentThread().getName()+"生产者"+this.name); flag = true; condition_consume.signal(); // After the producer finishes producing, wake up the consumer's process (no longer signalAll) } catch (InterruptedException e1) { e1.printStackTrace(); }finally { lock.unlock(); } } public synchronized void out() { lock.lock(); try{ //1) Loop judgment while(!flag){ condition_consume.await(); } Thread.sleep(600); System.out.println(Thread.currentThread().getName()+" ....消费者...."+this.name); flag =false; condition_pro.signal(); // After the consumer finishes consuming, wake up the producer's process } catch (InterruptedException e) { e.printStackTrace (); }// Simulate consumption time finally { lock.unlock(); } } } class Resources { private String name; private int count =1; private boolean flag =false; public synchronized void set(String name) { //1) Loop judgment while(flag) try{this.wait();}catch(Exception e){} this.name = name+"--"+count++; try { Thread.sleep(200) ; } catch (InterruptedException e) { e.printStackTrace (); }// Simulate production time System.out.println(Thread.currentThread().getName()+"生产者"+this.name); flag =true; //2) Wake up all processes this.notifyAll(); } public synchronized void out() { //1) Loop judgment while(!flag) try{this.wait();}catch(Exception e){} try { Thread.sleep(200) ; } catch (InterruptedException e) { e.printStackTrace (); }// Simulate consumption time System.out.println(Thread.currentThread().getName()+" ....消费者...."+this.name); flag =false; //2) Wake up all processes this.notifyAll(); } }