我尝试运行“Herbert Schildt的JAVA 2”一书中编写的代码。这是代码
class Q
{
int n;
boolean valueSet = false;
synchronized int get() {
if(!valueSet) {
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
}
System.out.println("Got: " + n);
valueSet=false;
notify();
return n;
}
synchronized void put(int n) {
System.out.println("Put method called");
if(valueSet) {
try {
System.out.println("Put method if check called");
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n=n;
valueSet=true;
System.out.println("Put: " + n);
notify();
}
}
}
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q=q;
new Thread(this,"Producer").start();
}
public void run() {
int i=0;
while(true) {
q.put(i++);
}
}
}
class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q=q;
new Thread(this,"Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}
}
class PcFixed {
public static void main(String[] args) {
System.out.println("main thread started");
Q obj = new Q();
new Producer(obj);
new Consumer(obj);
}
}
它应该给出的输出是
把:1
GOT:1
把:2
GOT:2
把:3
GOT:3
把:4
GOT:4
把:5
GOT:5
但我的问题是,当线程在Producer
构造函数中启动时,它调用run()
,然后进入调用while
的{{1}}循环。但它一次又一次地执行q.put()
的第一个语句(无限循环)。为什么这样做?
答案 0 :(得分:0)
valueSet永远不会设置为true,因为唯一的true赋值在if(valueSet){...}块中。
您需要将this.n = n和后续行移出if(valueSet){...}块。
BTW,虽然理解这些东西有其用途,但在java.util.concurrent中使用更高级别的并发类(例如阻塞队列)通常是目前更好的方法。