Producer consumer model
See the following code
/** * @program: demo * @description: Producer * @author: lee * @create: 2018-08-29 **/ public class Product { private String lock; public Product(String lock) { this.lock = lock; } public void setValue() { try { synchronized (lock) { if (!ValueObjec.value.equals("")) { lock.wait(); } String value = System.currentTimeMillis() + "_"+ System.nanoTime(); System.out.println("set The value is"+value); ValueObjec.value=value; lock.notify(); } } catch (InterruptedException ex) { ex.printStackTrace(); } } } /** * @program: demo * @description: Consumer * @author: lee * @create: 2018-08-29 **/ public class Consume { private String lock; public Consume() { } public Consume(String lock) { this.lock = lock; } public void getValue() { try { synchronized (lock) { if (ValueObjec.value.equals("")) { lock.wait(); } String value = ValueObjec.value; System.out.println("get The value is"+value); ValueObjec.value=""; lock.notify(); } } catch (InterruptedException ex) { ex.printStackTrace(); } } } /** * @program: demo * @description: Main thread * @author: lee * @create: 2018-08-29 **/ public class Run { public static void main(String[] args) { String lock = new String(""); Thread thread = new Thread(new ThreadA(new Product(lock))); thread.start(); Thread thread2 = new Thread(new ThreadB(new Consume(lock))); thread2.start(); } } /** * @program: demo * @description: thread * @author: lee * @create: 2018-08-29 **/ public class ThreadA implements Runnable { private Product product; public ThreadA(Product product) { this.product = product; } @Override public void run() { while (true) { product.setValue(); } } } /** * @program: demo * @description: thread * @author: lee * @create: 2018-08-29 **/ public class ThreadB implements Runnable{ private Consume consume; public ThreadB(Consume consume) { this.consume = consume; } @Override public void run() { while (true) { consume.getValue(); } } } /** * @program: demo * @description: demo * @author: lee * @create: 2018-08-29 **/ public class ValueObjec { public static String value=""; }
Output result
.... The value of get is 1535543013723_ The value of set is 1535543013723_ The value of get is 1535543013723_ The value of set is 1535543013723_ The value of get is 1535543013723_ The value of set is 1535543013723_ The value of get is 1535543013723_ The value of set is 1535543013723_ The value of get is 1535543013723_ The value of set is 1535543013723_ The value of get is 1535543013723_ The value of set is 1535543013723_ ...
More production and more consumption
The pseudo dead state is that the thread enters the waiting state. If all threads enter the waiting state, the program will not perform any business functions, and the whole project will be in a stagnant state.
See the following code
/** * @program: demo * @description: Consumer * @author: lee * @create: 2018-08-29 **/ public class Consume { private String lock; public Consume() { } public Consume(String lock) { this.lock = lock; } public void getValue() { try { synchronized (lock) { if (ValueObjec.value.equals("")) { System.out.println("Consumer" + Thread.currentThread().getName() + "*********Enter wait*******"); lock.wait(); } String value = ValueObjec.value; System.out.println("get The value is"+value); ValueObjec.value=""; lock.notify(); } } catch (InterruptedException ex) { ex.printStackTrace(); } } } /** * @program: demo * @description: Producer * @author: lee * @create: 2018-08-29 **/ public class Product { private String lock; public Product(String lock) { this.lock = lock; } public void setValue() { try { synchronized (lock) { if (!ValueObjec.value.equals("")) { System.out.println("Producer" + Thread.currentThread().getName() + "*********Enter wait*******"); lock.wait(); } String value = System.currentTimeMillis() + "_"+ System.nanoTime(); System.out.println("set The value is"+value); ValueObjec.value=value; lock.notify(); } } catch (InterruptedException ex) { ex.printStackTrace(); } } } /** * @program: demo * @description: Main thread * @author: lee * @create: 2018-08-29 **/ public class Run { public static void main(String[] args) { String lock = new String(""); Thread thread = new Thread(new ThreadA(new Product(lock))); thread.start(); Thread thread2 = new Thread(new ThreadA(new Product(lock))); thread2.start(); Thread thread3 = new Thread(new ThreadA(new Product(lock))); thread3.start(); Thread threadB = new Thread(new ThreadB(new Consume(lock))); threadB.start(); Thread threadB1 = new Thread(new ThreadB(new Consume(lock))); threadB1.start(); Thread threadB2 = new Thread(new ThreadB(new Consume(lock))); threadB2.start(); Thread threadB3 = new Thread(new ThreadB(new Consume(lock))); threadB3.start(); } } /** * @program: demo * @description: thread * @author: lee * @create: 2018-08-29 **/ public class ThreadA implements Runnable { private Product product; public ThreadA(Product product) { this.product = product; } @Override public void run() { while (true) { product.setValue(); } } } /** * @program: demo * @description: thread * @author: lee * @create: 2018-08-29 **/ public class ThreadB implements Runnable{ private Consume consume; public ThreadB(Consume consume) { this.consume = consume; } @Override public void run() { while (true) { consume.getValue(); } } } /** * @program: demo * @description: demo * @author: lee * @create: 2018-08-29 **/ public class ValueObjec { public static String value=""; }
This multi production and multi consumption program is very unsafe, because the notify method can only guarantee to wake up one program at a time. If the wake-up program is not a heterogeneous program but a similar program, such as the producer wakes up the producer, if it continues to run like this, it may cause all programs to fall into a waiting state.
Feign death solution
To solve the problem of pseudo death, when there is more production and more consumption, all threads are awakened when the thread is awakened, that is, the notifyAll method is used, so that the situation of pseudo death can be avoided.
public class Consume { private String lock; public Consume() { } public Consume(String lock) { this.lock = lock; } public void getValue() { try { synchronized (lock) { if (ValueObjec.value.equals("")) { System.out.println("Consumer" + Thread.currentThread().getName() + "*********Enter wait*******"); lock.wait(); } String value = ValueObjec.value; System.out.println("get The value is"+value); ValueObjec.value=""; lock.notifyAll(); } } catch (InterruptedException ex) { ex.printStackTrace(); } } } public class Product { private String lock; public Product(String lock) { this.lock = lock; } public void setValue() { try { synchronized (lock) { if (!ValueObjec.value.equals("")) { System.out.println("Producer" + Thread.currentThread().getName() + "*********Enter wait*******"); lock.wait(); } String value = System.currentTimeMillis() + "_"+ System.nanoTime(); System.out.println("set The value is"+value); ValueObjec.value=value; lock.notifyAll(); } } catch (InterruptedException ex) { ex.printStackTrace(); } } }