JAVA多執行緒--實現生產者/消費者模型:一對一
阿新 • • 發佈:2019-01-12
要實現的功能:執行緒A將一個數據放入佇列,然後通知B進行處理,B處理完後再通知A放一個數據入佇列。
package javathreadlearn; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; public class ReentrantLockTest { public static ReentrantLock lock = new ReentrantLock(); public static Condition condition = lock.newCondition(); public static LinkedList<String> queue = new LinkedList<>(); public static boolean hasCompleted = false; public static void main(String[] args){ ThreadA a = new ThreadA(); ThreadB b = new ThreadB(); b.setName("thread-B"); a.start(); b.start(); try { a.join(); }catch (InterruptedException e){ e.printStackTrace(); } } } class ThreadA extends Thread{ @Override public void run(){ for (int i = 0;i<10;i++) { try{ ReentrantLockTest.lock.lock(); while (ReentrantLockTest.hasCompleted == true){ ReentrantLockTest.condition.await(); } ReentrantLockTest.queue.add(String.valueOf(i)); ReentrantLockTest.hasCompleted = true; ReentrantLockTest.condition.signal(); } catch (InterruptedException e){ e.printStackTrace(); }finally { ReentrantLockTest.lock.unlock(); } } } } class ThreadB extends Thread{ @Override public void run(){ while (true) { try{ ReentrantLockTest.lock.lock(); while (ReentrantLockTest.hasCompleted == false){ ReentrantLockTest.condition.await(); } System.out.println(ReentrantLockTest.queue.remove()); ReentrantLockTest.hasCompleted = false; ReentrantLockTest.condition.signal(); } catch (InterruptedException e){ e.printStackTrace(); }finally { ReentrantLockTest.lock.unlock(); } } } }
程式碼執行結果如下所示:
0
1
2
3
4
5
6
7
8
9
A-exit
可以看到,A結束了,但是B還是在執行。如何解決呢?
可以用 interrupt來打標記。然後在B執行緒中檢測標記,如果結束就退出迴圈。