博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA 线程之守护线程Daemon Thread
阅读量:4209 次
发布时间:2019-05-26

本文共 10773 字,大约阅读时间需要 35 分钟。

在Java中有两类线程:

用户线程 (User Thread) 和 守护线程 (Daemon Thread)。

守护线程

  1. 是指在程序运行的时候在后台提供一种通用服务的线程,并不属于程序中不可或缺的部分

  2. 当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程

用户线程和守护线程区别:

唯一的不同之处就在于虚拟机的离开:如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。 因为没有了被守护者,守护线程也就没有工作可做了,也就没有继续运行程序的必要了。

将线程转换为守护线程

通过调用Thread对象的setDaemon(true)方法来实现。在使用守护线程时需要注意一下几点:

  1. 必须在start()方法之前设置

    thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。

  2. 在Daemon线程中产生的新线程也是Daemon的

  3. 守护线程应该永远不去访问固有资源,如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生中断

编写实例

  1. 编写DeamonThread类实现往文件中写入数据的功能
  2. 在主线程中将DeamonThread设置为守护线程 并且使用键盘输入模拟阻塞状态
  3. 当从键盘输入后从阻塞状态进入运行状态 主线程执行结束 守护线程也结束

DeamonThread :

package thread.demo3;import java.io.*;/** * 守护线程DeamonThread * Created by heqianqian on 2017/4/15. */public class DeamonThread implements Runnable {
private int count = 0; @Override public void run() { System.out.println("Deamon Thread Running...."); File file = new File("Base/file/deamon/file.txt"); OutputStream outputStream = null; try { outputStream = new FileOutputStream(file, true); while (count < 999) { outputStream.write(("word:"+count+"\r\n").getBytes()); System.out.println(Thread.currentThread().getName()+" write word "+count++); Thread.sleep(1000); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } finally { if (outputStream!=null){ try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } System.out.println("Deamon Thread Over!"); }}

Main:

package thread.demo3;import java.util.Scanner;/** * Main * Created by heqianqian on 2017/4/15. */public class Main {
public static void main(String[] args) { System.out.println("Main Thread Running...."); DeamonThread deamonThread = new DeamonThread(); Thread thread = new Thread(deamonThread); thread.setDaemon(true);//设置为守护线程 且必须在start前调用 thread.start(); Scanner scanner = new Scanner(System.in); scanner.next();//模拟阻塞 System.out.println("Main Thread Over!"); }}

运行结果:

这里写图片描述

file.txt文件内容:

这里写图片描述

使用jstack生成线程快照

运行程序后 打开任务管理器 找到当前程序的PID

这里写图片描述

打开CMD 输入

jstack -l pid

可以看到快照结果

这里写图片描述

我们可以分析一下

C:\Users\heqianqian>jstack -l 100922017-04-15 09:54:03Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.92-b14 mixed mode):"RMI RenewClean-[localhost:52353]" #18 daemon prio=5 os_prio=0 tid=0x00000000173ac000 nid=0x239c in Object.wait() [0x0000000017b0f000]   java.lang.Thread.State: TIMED_WAITING (on object monitor)        at java.lang.Object.wait(Native Method)        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)        - locked <0x00000000d01df4c0> (a java.lang.ref.ReferenceQueue$Lock)        at sun.rmi.transport.DGCClient$EndpointEntry$RenewCleanThread.run(DGCClient.java:553)        at java.lang.Thread.run(Thread.java:745)   Locked ownable synchronizers:        - None"RMI Scheduler(0)" #17 daemon prio=5 os_prio=0 tid=0x00000000173a9000 nid=0x255c waiting on condition [0x0000000017a0e000]   java.lang.Thread.State: TIMED_WAITING (parking)        at sun.misc.Unsafe.park(Native Method)        - parking to wait for  <0x00000000d02c2350> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)        at java.lang.Thread.run(Thread.java:745)   Locked ownable synchronizers:        - None"GC Daemon" #14 daemon prio=2 os_prio=-2 tid=0x000000001648b800 nid=0x2428 in Object.wait() [0x0000000016f0e000]   java.lang.Thread.State: TIMED_WAITING (on object monitor)        at java.lang.Object.wait(Native Method)        at sun.misc.GC$Daemon.run(GC.java:117)        - locked <0x00000000d02c2510> (a sun.misc.GC$LatencyLock)   Locked ownable synchronizers:        - None"RMI Reaper" #13 prio=5 os_prio=0 tid=0x0000000016607000 nid=0x2268 in Object.wait() [0x0000000016e0f000]   java.lang.Thread.State: WAITING (on object monitor)        at java.lang.Object.wait(Native Method)        - waiting on <0x00000000d01dfac0> (a java.lang.ref.ReferenceQueue$Lock)        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)        - locked <0x00000000d01dfac0> (a java.lang.ref.ReferenceQueue$Lock)        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)        at sun.rmi.transport.ObjectTable$Reaper.run(ObjectTable.java:351)        at java.lang.Thread.run(Thread.java:745)   Locked ownable synchronizers:        - None"RMI TCP Accept-0" #12 daemon prio=5 os_prio=0 tid=0x000000001655e000 nid=0x24a0 runnable [0x0000000016d0e000]   java.lang.Thread.State: RUNNABLE        at java.net.DualStackPlainSocketImpl.accept0(Native Method)        at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:131)        at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)        at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199)        - locked <0x00000000d01df1b0> (a java.net.SocksSocketImpl)        at java.net.ServerSocket.implAccept(ServerSocket.java:545)        at java.net.ServerSocket.accept(ServerSocket.java:513)        at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:400)        at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:372)        at java.lang.Thread.run(Thread.java:745)   Locked ownable synchronizers:        - None"RMI TCP Accept-34855" #11 daemon prio=5 os_prio=0 tid=0x0000000016243800 nid=0x2338 runnable [0x0000000016c0f000]   java.lang.Thread.State: RUNNABLE        at java.net.DualStackPlainSocketImpl.accept0(Native Method)        at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:131)        at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)        at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199)        - locked <0x00000000d0211318> (a java.net.SocksSocketImpl)        at java.net.ServerSocket.implAccept(ServerSocket.java:545)        at java.net.ServerSocket.accept(ServerSocket.java:513)        at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:400)        at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:372)        at java.lang.Thread.run(Thread.java:745)   Locked ownable synchronizers:        - None"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x0000000016296000 nid=0x284c runnable [0x0000000000000000]   java.lang.Thread.State: RUNNABLE   Locked ownable synchronizers:        - None"C1 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x000000001621b000 nid=0x27c0 waiting on condition [0x0000000000000000]   java.lang.Thread.State: RUNNABLE   Locked ownable synchronizers:        - None"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x0000000016215800 nid=0x286c waiting on condition [0x0000000000000000]   java.lang.Thread.State: RUNNABLE   Locked ownable synchronizers:        - None"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x0000000014c8d000 nid=0x26f0 waiting on condition [0x0000000000000000]   java.lang.Thread.State: RUNNABLE   Locked ownable synchronizers:        - None"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0000000014c8b800 nid=0x27a0 waiting on condition [0x0000000000000000]   java.lang.Thread.State: RUNNABLE   Locked ownable synchronizers:        - None"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x0000000014c40000 nid=0x2780 runnable [0x0000000000000000]   java.lang.Thread.State: RUNNABLE   Locked ownable synchronizers:        - None"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000002ebd000 nid=0x279c in Object.wait() [0x0000000015faf000]   java.lang.Thread.State: WAITING (on object monitor)        at java.lang.Object.wait(Native Method)        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)        - locked <0x00000000d02c32b0> (a java.lang.ref.ReferenceQueue$Lock)        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)   Locked ownable synchronizers:        - None"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000002eb2000 nid=0x26e0 in Object.wait() [0x0000000015eaf000]   java.lang.Thread.State: WAITING (on object monitor)        at java.lang.Object.wait(Native Method)        at java.lang.Object.wait(Object.java:502)        at java.lang.ref.Reference.tryHandlePending(Reference.java:191)        - locked <0x00000000d02ea1c8> (a java.lang.ref.Reference$Lock)        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)   Locked ownable synchronizers:        - None"main" #1 prio=5 os_prio=0 tid=0x0000000002dc2800 nid=0x2844 in Object.wait() [0x00000000029ff000]   java.lang.Thread.State: TIMED_WAITING (on object monitor)        at java.lang.Object.wait(Native Method)        at com.intellij.execution.rmi.RemoteServer.start(RemoteServer.java:86)        - locked <0x00000000d02c3350> (a java.lang.Object)        at org.jetbrains.idea.maven.server.RemoteMavenServer.main(RemoteMavenServer.java:22)   Locked ownable synchronizers:        - None"VM Thread" os_prio=2 tid=0x0000000014bf7000 nid=0x2794 runnable"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002dd8800 nid=0x2878 runnable"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002dda000 nid=0x2804 runnable"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002ddb800 nid=0x1d9c runnable"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002ddd000 nid=0x25e8 runnable"VM Periodic Task Thread" os_prio=2 tid=0x00000000162dc000 nid=0x27c4 waiting on conditionJNI global references: 236C:\Users\heqianqian>
  1. Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.92-b14 mixed mode)
    线程块运行在java虚拟机hotspot上 是64位的服务端
  2. 接下来是一些java自带的守护进程
    比如GC线程

这里写图片描述

可以看到是deamon线程 优先级是2 当前状态为有时间的等待状态

Locked ownable synchronizers 是否处于同步块中

最后显示的是我们的主线程

这里写图片描述

可以看到主线程并不是一个守护线程 并且处于等待状态 原因是我们的键盘输入阻塞了主线程

jstack使用参数

这里写图片描述


参考文章:

你可能感兴趣的文章
Python UnicodeEncodeError: 'gbk' codec can't encode character 解决方法
查看>>
Google 渗透工具-搜集信息
查看>>
spring boot 访问服务器的文件
查看>>
什么是安全证书,访问者到底是怎么校验安全证书的,服务端返回安全证书后,客户端再向谁验证呢?
查看>>
SMTP具体发信的步骤
查看>>
mysql查询结果输出到文件
查看>>
邮件交换器记录(MX)的使用
查看>>
HDFS:如何将文件从HDFS复制到本地
查看>>
HDFS:如何复制文件
查看>>
Intellij IEDA: the working directory does not exist
查看>>
java正则表达式转义和反斜杠
查看>>
Java中比较两个字符串是否相等的问题
查看>>
Java正则表达式匹配模式[贪婪型、勉强型、占有型]
查看>>
Ubuntu终端Terminal常用快捷键 暂停屏幕输出
查看>>
java List<String>的初始化
查看>>
Java发送Http请求并获取状态码
查看>>
HttpClient获取响应状态Status
查看>>
java中判断文件是否是图片文件
查看>>
BufferedImage与byte[]互转
查看>>
Java去除字符串中的空格
查看>>