繁体   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