[英]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类。
检索并删除此队列的头,如有必要,请等待直到元素可用。
进行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.