Java ArrayDeque die in Multiple threads

今天遇到一個問題

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();
    }
}

 © 2024 - 二三往事