簡體   English   中英

線程未與單鎖同步

[英]Thread not synchronized with single lock

我無法正確同步該程序,第二個println中的結果也應該為0,因為兩個線程各自創建並彈出10000次。 我是否必須以其他方式進行同步?

import java.util.*;

public class Main00 {

Queue<Integer> q = new PriorityQueue<Integer>();
Random rand = new Random();

public static void main(String[] args) {
    new Main00().doStuff();
}

public void doStuff(){
    Thread t1=new Thread(new Runnable(){
        public void run(){
            for(int i=0;i<10000;i++)produce();
        }
    });
    Thread t2=new Thread(new Runnable(){
        public void run(){
            for(int i=0;i<10000;i++)consume();
        }
    });

    System.out.println("Starting threads, q size is : "+q.size());
    t1.start();
    t2.start();

    try{
        t1.join();
        t1.join();
    }catch(InterruptedException e){}

    System.out.println("Ending threads, q size is : "+q.size());
}

synchronized public void produce() {
    q.add(rand.nextInt(100));
}

synchronized public void consume() {
    q.poll();
}

}

您沒有加入第二個線程:

    t1.join();
    t1.join();

應該:

    t1.join();
    t2.join();

您還使用了不會阻止的poll

檢索並刪除此隊列的頭部,如果此隊列為空,則返回null。

您可能要使用PriorityBlockingQueue

如果任何線程修改了隊列,則多個線程不應同時訪問PriorityQueue實例。 而是使用線程安全的PriorityBlockingQueue類。

您可以利用take方法來避免忙碌

檢索並刪除此隊列的頭,如有必要,請等待直到元素可用。

進行poll的調用不一定會消耗一個元素。 如果隊列中沒有元素,則僅返回null。

為了確保您有效地使用了元素,您可以編寫:

  while(q.poll() == null);

此外,類PriorityQueue不是線程根據http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html 您應該使用線程安全的PriorityBlockingQueue類,該類具有poll方法,該方法會因超時而阻塞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM