今天遇到一個問題
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();
}
}


[No preview: this is a protected post]

