- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的notifyAll()方法似乎都不起作用。露西应该等到鲍勃到达然后释放。鲍勃应该等待露西的确认然后释放。这些事情似乎都没有发生。
有人可以让我知道我做错了什么以及如何解决它。提前致谢。
编辑 - 我根据格雷的建议修改了我的代码。异常消失了,但 notify() 方法似乎仍然不起作用。
import java.util.logging.Level;
import java.util.logging.Logger;
public class PlayDates {
Thread lucyThread;
Girl lucy;
Thread bobThread;
Boy bob;
public static void main(String[] args) {
PlayDates playDates = new PlayDates();
playDates.run();
}
public void run() {
lucy = new Girl();
lucyThread = new Thread(lucy);
bob = new Boy();
bobThread = new Thread(bob);
lucyThread.start();
threadSleep(500);
bobThread.start();
}
public class Girl implements Runnable {
@Override
public void run() {
synchronized(PlayDates.this){
System.out.println("Girl synchronized hit");
if(!bob.hasArrived()) { // Doesnt seem to get past here?
System.out.println("Lucy has fallen asleep waiting for Bob");
try {
PlayDates.this.wait(); // Wait for Bob
System.out.println("Lucy has woken up");
PlayDates.this.notifyAll(); // Acknowledge Bobs arrival
} catch (InterruptedException ex) {
Logger.getLogger(PlayDates.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
public class Boy implements Runnable {
private boolean hasArrived;
@Override
public void run() {
synchronized(PlayDates.this){
System.out.println("Bob has arrived to play");
PlayDates.this.notifyAll();
try {
PlayDates.this.wait(); // Wait for Lucy to acknowledge Bobs arrival
} catch (InterruptedException ex) {
Logger.getLogger(PlayDates.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Bob and Lucy are playing");
}
}
public Boy() {
hasArrived = true;
}
public boolean hasArrived() {
return hasArrived;
}
}
public void threadSleep(int milli) {
try {
Thread.sleep(milli);
} catch (InterruptedException ex) {
Logger.getLogger(PlayDates.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
电流输出
Girl synchronized hit
Bob has arrived to play
<小时/>
编辑2我已经按照格雷的建议调整了我的代码。hasArrived 现在是不稳定的并且位于 playDates run 方法中。它在内部类 Boys run 方法中更改为 true。输出没有改变,问题似乎是一样的。还有进一步的建议吗?
更新的代码:
import java.util.logging.Level;
import java.util.logging.Logger;
public class PlayDates {
Thread lucyThread;
Girl lucy;
Thread bobThread;
Boy bob;
volatile boolean hasArrived;
public static void main(String[] args) {
PlayDates playDates = new PlayDates();
playDates.run();
}
public void run() {
hasArrived = false;
lucy = new Girl();
lucyThread = new Thread(lucy);
bob = new Boy();
bobThread = new Thread(bob);
lucyThread.start();
threadSleep(500);
bobThread.start();
}
public class Girl implements Runnable {
@Override
public void run() {
synchronized(PlayDates.this){
System.out.println("Girl synchronized hit");
if(hasArrived) { // Doesnt seem to get past here?
System.out.println("Lucy has fallen asleep waiting for Bob");
try {
PlayDates.this.wait(); // Wait for Bob
System.out.println("Lucy has woken up");
PlayDates.this.notifyAll(); // Acknowledge Bobs arrival
} catch (InterruptedException ex) {
Logger.getLogger(PlayDates.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
public class Boy implements Runnable {
@Override
public void run() {
threadSleep(1000);
synchronized(PlayDates.this){
System.out.println("Bob has arrived to play");
hasArrived = true;
PlayDates.this.notifyAll();
try {
PlayDates.this.wait(); // Wait for Lucy to acknowledge Bobs arrival
} catch (InterruptedException ex) {
Logger.getLogger(PlayDates.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Bob and Lucy are playing");
}
}
}
public void threadSleep(int milli) {
try {
Thread.sleep(milli);
} catch (InterruptedException ex) {
Logger.getLogger(PlayDates.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
最佳答案
您正在启动Girl
初始化 bob
之前的线程字段,这样你就会得到一个 NPE。您应该初始化您的 bob
字段之前 Girl
并应该将其传递到该线程中。您的程序可能在某些情况下有效,但存在不可预测的竞争条件。如果线程启动得足够快,它可能会工作,但您应该初始化 bob
在开始Girl
之前线程。
你还有一些memory synchronization issues 。例如,尽管您正在 PlayDates.this
上同步,Boy
Girl
时,类可能尚未初始化和同步。线程调用bob.hasArrived()
。每当在多个线程中访问一个字段时,您需要确保两个线程都看到正确同步的值。您可以通过设置hasArrived
来确保这一点成为 AtomicBoolean
或标记 hasArrived
作为volatile
.
编辑:
问题正在发生变化,所以我会尽力跟上。我建议不要设置 hasArrived
是真实的Boy
构造函数。我认为你应该做到 volatile
并设置在 run()
方法。您想要Girl
线程启动,运行一下,然后看到 Boy
不可用并且 wait()
。所以Boy
线程应该稍后启动并设置 hasArrived
成为true
在它的run()
sleep()
之后的方法.
关于java - 为什么我的notify()不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16123456/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!