今天遇到一個問題
Java 的 ArrayDeque 並非執行序安全的物件,在多執行緒的狀況下,會卡死,導致使用poll時,任何東西都拿不出來。
解決方法很簡單單,上個synchronized去鎖住就行了。
因為我原本在使用這個東西的程式碼中,在別的地方有用lock去控制執行緒,再加上認為這邊應該只會造成順序亂掉之類的問題,就沒上synchronized,沒想到ArrayDeque會死到連東西都拿不出來。
package com.f23ko.test; import java.util.ArrayDeque; import java.util.Deque; import java.util.Map; /** * Created by f23ko on 2016/10/5. * * sysout: * take(3) put(3) diff(0) * take(326) put(866) diff(540) * take(1746) put(1751) diff(5) * take(2629) put(2637) diff(8) * take(3515) put(3523) diff(8) * take(4400) put(4408) diff(8) * take(4718) put(5285) diff(567) <= ArrayDeque die * take(4718) put(6164) diff(1446) * take(4718) put(7047) diff(2329) */ public class QueueTest { static Deque<Integer> queue=new ArrayDeque<>(); static int take=0; static int put=0; static void take() { while (true){ Integer t= queue.poll(); if(t!=null){ take++; continue; } try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } static void put() { int i=0; while (true){ i++; queue.offer(i); put++; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } static void print(){ while (true){ int t=take; int p=put; System.out.println("take("+t+") put("+p+") diff("+(p-t)+")"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args){ new Thread(QueueTest::put).start(); new Thread(QueueTest::put).start(); new Thread(QueueTest::put).start(); new Thread(QueueTest::take).start(); new Thread(QueueTest::print).start(); } }