线程与单锁不同步
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
,它不会阻塞:
Retrieves and removes the head of this queue, or returns null if this queue is empty.
您可能想使用 PriorityBlockingQueue
:
Multiple threads should not access a PriorityQueue instance concurrently if any of the threads modifies the queue. Instead, use the thread-safe PriorityBlockingQueue class.
您可以利用 take
method to avoid busy-wait:
Retrieves and removes the head of this queue, waiting if necessary until an element becomes available.
对 poll
的调用不一定会消耗元素。如果队列中没有元素,它只是 returns null.
为了确保你有效地使用一个元素,你会写:
while(q.poll() == null);
此外,根据 http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html,class PriorityQueue
不是线程安全的。您应该使用线程安全的 PriorityBlockingQueue
class,它有一个 poll
超时阻塞方法。
我无法正确同步此程序,第二个 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
,它不会阻塞:
Retrieves and removes the head of this queue, or returns null if this queue is empty.
您可能想使用 PriorityBlockingQueue
:
Multiple threads should not access a PriorityQueue instance concurrently if any of the threads modifies the queue. Instead, use the thread-safe PriorityBlockingQueue class.
您可以利用 take
method to avoid busy-wait:
Retrieves and removes the head of this queue, waiting if necessary until an element becomes available.
对 poll
的调用不一定会消耗元素。如果队列中没有元素,它只是 returns null.
为了确保你有效地使用一个元素,你会写:
while(q.poll() == null);
此外,根据 http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html,class PriorityQueue
不是线程安全的。您应该使用线程安全的 PriorityBlockingQueue
class,它有一个 poll
超时阻塞方法。