1.最近在学习Java多线程,看到视频中要实现一个类似闹钟和小明的情景, 要求闹钟响,小明关闹钟, 三秒后闹钟再响,小明再关, 重复10次程序结束. 不知道为什么我的程序小明只能输出一次.
public class Test {
public static void main(String[] args) {
Clock ck = new Clock();
new XiaoMing(ck);
}
}
public class Clock implements Runnable{
public Boolean isAlarm;
public Boolean shutdown;
public Clock() {
isAlarm = false;
shutdown = false;
new Thread(this).start();
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
isAlarm = true;
System.out.println("Get up * 3 !");
synchronized (this) {
notifyAll();
try {
wait(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
shutdown = true;
}
}
public class XiaoMing implements Runnable{
private Clock clk;
public XiaoMing(Clock clk) {
this.clk = clk;
new Thread(this).start();
}
@Override
public void run() {
while(true) {
if (clk.isAlarm) {
System.out.println("Woshixiaoming!");
clk.isAlarm = false;
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
else{
if(clk.shutdown) break;
}
}
}
}
输出结果如下
Get up * 3 !
Woshixiaoming!
Get up * 3 !
Get up * 3 !
...(10 次 Getup, 之后程序停在那里)
楼主你的Clock 方法也个问题,你的程序逻辑是clock唤醒->XiaoMing等待,然而在第十次循环结束后,XiaoMing没有迎来第十一次的唤醒让他break出去,一直在默默等待,修改后Clock的run方法如下:
@Override
public void run() {
for (int i = 0; i < 10; i++) {
isAlarm = true;
System.out.println("Get up * 3 !");
synchronized (this) {
notifyAll();
try {
wait(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
shutdown = true;
synchronized (this) {
notifyAll();
}
}
这是因为你没有理解到wait(),notify(),notifyAll()
这三个方法的真正作用,它们不是控制的所有线程,而是所对象的线程。
也就是说,XiaoMing 的同步锁里调用的 wait()
方法阻塞的是 XiaoMing 这个线程;Clock
的同步锁唤醒的是 Clock
类的对象的线程,所以 XiaoMing 的对象的线程就一直阻塞下去了
可以修改 XiaoMing 类run()
方法的同步锁
@Override
public void run() {
while(true) {
if (clk.isAlarm) {
System.out.println("Woshixiaoming!");
clk.isAlarm = false;
synchronized (this.clk) {
try {
this.clk.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
else{
if(clk.shutdown) break;
}
}
}
这样 XiaoMing 的线程会因为clk域被阻塞,直到Clock的线程调用notifyAll()
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。