Java 多线程

新手上路,请多包涵

题目描述

最近在学习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();
}

你期待的结果是什么?实际看到的错误信息又是什么?

请问一下 为什么在注释的哪里添加一个锁,代码就能执行完成,去掉这个锁,代码就死锁了呢?

阅读 1.8k
1 个回答

这是一个关于可见性的问题
简单的说就是 quit 变量的改变没有被循环那看到,循环读取的quit变量一直是缓存中的
解决方法也很简单,申明quit的时候加上volatile就好啦
另外synchronized 因为可以保证可见性,也就是你注释的地方
public synchronized void quit()在解锁时会把quit变量的值刷新回内存
synchronized(this)加锁时会从内存中重新获取最新的quit的值

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题