Background:
When I tested the multi-production and multi-consumption operation values - suspended animation, there were two production and consumption threads respectively, and each thread looped the corresponding method twice.
Problem :
Print the log and found that consumption 2 has a wait before it wakes up Then it went down and executed, I don't know why?
Attach the test code
first . There is always
consumer 2 WAITING 0 in the log. Releasing value=null
Consumer 2 WAITING 1
Normal release of value is followed by value, but this time it does not. Although it does not affect the function, it is very strange.
/** * 3.1.11.2 Multi-production and multi-consumption operation value - suspended animation * Created by ironlee on 17/12/23. */ public class ProducerAndConsumerAllWait { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } /** * Production * @param lock */ public void producer(Object lock){ synchronized (lock){ try { int i = 0 ; while(StringUtils.isNotBlank(getValue())) { System.out.println(Thread.currentThread().getName()+" WAITING value="+getValue()+" "+(i++)); lock.wait(); } String value = System.currentTimeMillis()+"-"+System.nanoTime(); System.out.println(Thread.currentThread().getName()+" RUNNABLE value="+value); setValue(value); lock.notify(); // System.out.println(System.currentTimeMillis()+"-"+System.nanoTime()+" 生产者 "+Thread.currentThread().getName()+" NOTIFY value="+getValue()); } catch (InterruptedException e) { e.printStackTrace (); } } } /** * Consumption * @param lock */ public void consumer(Object lock){ synchronized (lock){ try{ int i = 0 ; // Why didn't wake up wait to go down? while(StringUtils.isBlank(getValue())){ System.out.println(Thread.currentThread().getName()+" WAITING "+(i)); lock.wait(); System.out.println(Thread.currentThread().getName()+" WAITING "+(i) + " 解除 value="+getValue()); i++; } System.out.println(Thread.currentThread().getName()+" RUNNABLE value="+getValue()); setValue(null); lock.notify(); // System.out.println(System.currentTimeMillis()+"-"+System.nanoTime()+" 消费者 "+Thread.currentThread().getName()+" NOTIFY value="+getValue()); }catch(InterruptedException e){ e.printStackTrace (); } } } public static void main(String[] args) { final Object lock = new Object(); final ProducerAndConsumerAllWait domain = new ProducerAndConsumerAllWait(); final int count = 2; Runnable producer = new Runnable() { @Override public void run() { synchronized (lock){ int i = 0 ; while( i < count ){ System.out.println( Thread.currentThread().getName()+" 序号="+i); domain.producer( lock ); i++; } } } }; Runnable consumer = new Runnable() { @Override public void run() { synchronized (lock){ int i = 0 ; while(i< count){ System.out.println( Thread.currentThread().getName()+" 序号="+i); domain.consumer( lock ); i++; } } } }; for (int ii = 0; ii <2; ii ++) { Thread producerT = new Thread(producer); producerT.setName("Producer"+(ii+1)); producerT.start (); Thread consumerT = new Thread(consumer); consumerT.setName("Consumer"+(ii+1)); consumerT.start(); } try { Thread.sleep( 1000L ); } catch (InterruptedException e) { e.printStackTrace (); } Thread[] threadArray = new Thread[Thread.currentThread().getThreadGroup().activeCount()]; Thread.currentThread().getThreadGroup().enumerate( threadArray ); for( Thread t : threadArray ){ System.out.println( t.getName() + " " + t.getState() ); } } }