题目描述
最近在学习Java多线程的内容,视频里面老师讲了一个实现多线程循环的实例,
题目来源及自己的思路
相关代码
public class HandlerThread extends Thread {
private Runnable task;
private boolean quit;
public Runnable getTask() {
return task;
}
public void setTask(Runnable task) {
this.task = task;
}
public synchronized void quit() {
this.quit = true;
System.out.println("=====quit====>" + this.quit);
}
public boolean isQuit() {
return quit;
}
public void setQuit(boolean quit) {
this.quit = quit;
}
@Override
public void run() {
super.run();
// System.out.println("=====run=====" + quit);
while (!quit) {
// System.out.println("=====run=====" + quit);
// synchronized (this) {//这里要是没有这个锁,代码就好像被死锁了。
if (task != null) {
task.run();
task = null;
}
// }
}
}
}
public static void main(String[] args) {
HandlerThread handlerThread = new HandlerThread();
handlerThread.setTask(new Runnable() {
@Override
public void run() {
System.out.println("hahahaha");
}
});
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handlerThread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handlerThread.quit();
}
你期待的结果是什么?实际看到的错误信息又是什么?
请问一下 为什么在注释的哪里添加一个锁,代码就能执行完成,去掉这个锁,代码就死锁了呢?
这是一个关于可见性的问题
简单的说就是
quit
变量的改变没有被循环那看到,循环读取的quit
变量一直是缓存中的解决方法也很简单,申明
quit
的时候加上volatile
就好啦另外
synchronized
因为可以保证可见性,也就是你注释的地方public synchronized void quit()
在解锁时会把quit
变量的值刷新回内存synchronized(this)
加锁时会从内存中重新获取最新的quit
的值