PDF 课件和源代码下载地址:
https://gitee.com/geektime-geekbang/LetsJava
作者回复: 这个感觉是没有把目录标记为源代码目录,可以尝试右击源代码目录,选择Mark Directory as -> Source Root
作者回复: 有些线程就是为了为程序做一些清理或者辅助工作的。最原始的就是JVM里的执行finalize方法的线程(当然现在不推荐使用finalize方法了,这是另一说)。如果你现在debug一个Java进程,还能在frame里找到这个守护线程。 还有后面和守护线程有点关系的场景,就是发送心跳。在后面的聊天程序中,我们提出了一个心跳检查功能。因为客户端和服务器端的网络连接是不可靠的,所以对于一个成熟的软件来说,如果有涉及客户端和服务器端的长连接(可以简单认为不主动断开的连接,比如聊天的客户端服务器,HDFS等集群的worker和master的连接),都会使用心跳机制。简单来说,就是启动一个线程,然后定期发送一个心跳数据包,表示这边的程序还在正常工作。 而这个心跳线程,就应该在没有任何非守护线程的情况下结束。可以说是一个典型的守护线程的用例。 守护线程还有很多用例,可能具体的场景没有心跳检测这么直观。只要从业务逻辑上来说,这些线程不应该在没有别的工作线程在运行的情况下继续运行,那么这个线程就应该是守护线程。
作者回复: 对于刚刚接触编程的同学来说,多线程是比较绕的一点。代码是等待被执行被调用的东西,执行代码的主体就是线程。 打个比方,线程就好像一个演奏者,程序代码就是乐谱。多线程就是多个演奏者在演奏乐谱。 对于复杂的音乐,自然需要多个演奏者一同演奏。对应到程序,如果一个程序需要同时/并发做很多事情,那就需要用到多线程。
作者回复: 对于list里的每个Thread对象,调用Thread对象的interrupt方法。
作者回复: 你说的应该是这行代码 threads.forEach(Thread::interrupt); threads.forEach就是对threads里的每个线程进行处理,怎么处理呢?调用interrupt方法。你说的那个T,在这里就是Thread本身。至于调用哪个方法,相当于是lambda表达式的代码内容了。 扩展开,这个代码就是这样的 for(Thread t : threads){ t.interrupt(); }
作者回复: 是在视频哪个位置?
作者回复: 因为main线程在执行的时候等锁,锁被别的线程拿着不放,所以mian线程不能在这些线程之前结束。
作者回复: 完全✅
作者回复: 是的,SDK里抛出InterruptedException的方法,都是可以被interrupt()方法打断的。 我们自己的方法当然也可以做到,就像你说的,interrupt()只是设置了状态。我们要想响应interrupt(),那就时不时的检查一下这个状态。当然这是非常麻烦且丑陋的代码囧。
作者回复: 所有线程都退出进程就结束了