import java.util.ArrayList; import java.util.List; public class ProduceAndConsume { public static final Object signal = new Object(); public static List<String> list = new ArrayList<String>(); public static void main(String args[]) { Thread produce = new Thread(new Produce()); Thread consume = new Thread(new Consume()); produce.start(); consume.start(); } } class Produce implements Runnable{ @Override public void run() { int sequence = 0; while(true) { synchronized(ProduceAndConsume.signal){ for (int i = 0; i < 3; i++) { ProduceAndConsume.list.add(sequence + "commodity"); } sequence++; try { ProduceAndConsume.signal.notify(); ProduceAndConsume.signal.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } class Consume implements Runnable{ @Override public void run() { int count = 0; while(count < 5) { synchronized(ProduceAndConsume.signal) { try { ProduceAndConsume.signal.wait(); } catch (InterruptedException e) { e.printStackTrace(); } if(ProduceAndConsume.list.size() > 0) { for (String str : ProduceAndConsume.list) { System.out.println(str); } ProduceAndConsume.list.clear(); count++; ProduceAndConsume.signal.notify(); } } } } }
注意 java
1.消費和生產必定要用同一把鎖ProduceAndConsume.signal
2.ProduceAndConsume.signal.wait()的做用是當前線程暫停,釋放鎖signal,轉到等待隊列中,等待signal這個信號量(signal也是鎖)的通知。等到signal的通知以後(而不能是其餘信號量的通知),這個線程纔有機會轉到就緒隊列中,去競爭執行的機會。
3.ProduceAndConsume.signal.notify()的做用是通知等待在signal這個信號量的單個線程從等待隊列中進入就緒隊列,準備競爭執行的機會。但調用ProduceAndConsume.signal.notify()方法的線程並不會立刻釋放鎖,而是把代碼執行完後再釋放鎖,由於notify只是通知其餘等待在這個信號量的線程進入就緒隊列,準備競爭鎖。 ide