作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
谁能解释一下这个关于线程间通信的程序?
//生产者和消费者的正确实现。
class Q {
int n;
boolean valueSet = false;
synchronized int get() {
while(!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) {
while(valueSet)
try {
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[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}
输出
放:1得到:1放:2得到:2放:3得到:3放:4得到:4……
就我而言,这是非常困惑的,尤其是使用 notify() 和 wait() 的 put 和 get 方法。还请解释为什么使用 boolean 值。
最佳答案
所以有 2 个线程。 Qne 正在这个 Q 数据结构上设置值,另一个正在读取它们。 Q 使用 boolean 标志来判断是否存在新值,一旦读取现有值,标志就会被清除。
Q.get 使用等待阻塞,直到有新值可供读取。一旦读取到新值,它就会将标志设置回 false。
Q.put 等到另一个队列读取新值后才将其设置为新值,然后通过设置 boolean 标志并调用通知让另一个线程知道。
记住 wait 放弃锁以便其他线程可以获得它。
boolean 标志是必需的,因为线程可能会在没有得到通知的情况下停止等待。仅仅因为一个线程醒来并不意味着它收到了通知。此外,即使线程得到通知,因为线程在开始等待时放弃了锁,所以当前状态是未知的(通常有多线程程序,另一个线程可能会潜入并在线程之间抢断一些东西被通知和它可以重新获得锁的时间)所以线程一旦获得锁就必须再次重新测试条件。
像 wait 和 notify 这样的结构是大型并发程序的构建 block ,因此在只有两个线程的小示例中,有些事情可能没有多大意义。
关于java - 难以理解线程间通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23893851/
我是一名优秀的程序员,十分优秀!