Description of producer consumer mode: 1. the producer only produces when the warehouse is not full, and the producer process is blocked when the Warehouse is full; 2. consumers consume data only when the warehouse is not empty. When the Warehouse is empty, the consumer process is blocked. 3. the producer will be notified when the consumer finds that the warehouse is empty. 4. when the producer finds that the warehouse is full, it will notify the consumer of consumption. The key to implementation is: two synchronous methods in the shared memory and the wait () method calls in the synchronous method, synchronization ensures that the object can only be occupied by one thread. wait ensures that the lock is released while the thread is waiting, so that other objects have the opportunity to obtain the lock. In an object, the synchronized method is declared using synchonized. Java has a Synchronization Model-Monitor, which is responsible for managing the thread's access to the Synchronization Methods in the object. Its principle is: Assign the object a unique 'key'. When multiple threads enter the object, only the thread that obtains the object key can access the synchronization method. Other threads wait in the object until the thread uses the wait () method to discard the key, other threads waiting to seize the key can be executed only after the thread that grabs the key is obtained. threads without obtaining the key are still blocked and waiting in the object. All in all, synchonized enables only one thread to enter the critical code zone. Code implementation:
package com.thread; public class ProducerConsumer { public static void main(String[] args) { ShareData sd = new ShareData(); new Producer(sd).start(); new Consumer(sd).start(); } } class Producer extends Thread{ private ShareData sd; public Producer(ShareData sd){ this.sd = sd; } @Override public void run() { for(int i = 0; i < 20; i++){ int product = (int)(Math.random()*1000); sd.setArray(product); try { Thread.sleep((int)(Math.random()*200)); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Consumer extends Thread{ private ShareData sd; public Consumer(ShareData sd){ this.sd = sd; } @Override public void run() { for(int i = 0; i < 20; i++){ sd.getArray(); try { Thread.sleep((int)(Math.random()*200)); } catch (InterruptedException e) { e.printStackTrace(); } } } } class ShareData{ private static int shareArray[] = new int[10]; private int count; private int in; private int out; ShareData(){ this.count = 0; this.in = 0; this.out = 0; } public synchronized void setArray(int product){ try{ while(count >= shareArray.length){ System.out.println("array full."); this.wait(); } this.notify(); }catch (Exception e) { e.printStackTrace(); } shareArray[in] = product; count++; System.out.println("produce: " + product); in = (in + 1) % shareArray.length; } public synchronized int getArray(){ try{ while(count <= 0){ System.out.println("array empty."); this.wait(); } this.notify(); }catch(Exception e){ e.printStackTrace(); } int consume = shareArray[out]; count--; System.out.println("consume: " + consume); out = (out + 1) % shareArray.length; notify(); return consume; } }
Output code (different each time ):
array empty. produce: 86 consume: 86 array empty. produce: 232 consume: 232 array empty. produce: 438 consume: 438 produce: 272 consume: 272 array empty. produce: 495 consume: 495 produce: 354 produce: 533 consume: 354 produce: 92 consume: 533 produce: 374 consume: 92 produce: 441 produce: 141 consume: 374 consume: 441 consume: 141 array empty. produce: 68 consume: 68 produce: 978 consume: 978 array empty. produce: 737 consume: 737 array empty. produce: 904 consume: 904 array empty. produce: 613 consume: 613 array empty. produce: 812 consume: 812 produce: 726 produce: 326 consume: 726 produce: 305 consume: 326 consume: 305