守护线程

一般情况下:主线程会等待所有子线程运行完毕后在结束

java中线程分为两种类型:用户线程和守护线程。通过Thread.setDaemon(false)设置为用户线程;通过Thread.setDaemon(true)设置为守护线程。如果不设置次属性,默认为用户线程。

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

  1. 主线程结束后用户线程还会继续运行,JVM存活;主线程结束后守护线程和JVM的状态又下面第2条确定。

  2. .如果没有用户线程,都是守护线程,那么JVM结束(随之而来的是所有的一切烟消云散,包括所有的守护线程)。

补充说明:

定义:守护线程--也称“服务线程”,在没有用户线程可服务时会自动离开。

优先级:守护线程的优先级比较低,用于为系统中的其它对象和线程提供服务。

设置:通过setDaemon(true)来设置线程为“守护线程”;将一个用户线程设置为守护线程的方式是在线程启动用线程对象的setDaemon方法。
setDaemon(True)将线程声明为守护线程,必须在start() 方法调用之前设置,如果不设置为守护线程程序会被无限挂起

example: 垃圾回收线程就是一个经典的守护线程,当我们的程序中不再有任何运行的Thread,程序就不会再产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是JVM上仅剩的线程时,垃圾回收线程会自动离开。它始终在低级别的状态中运行,用于实时监控和管理系统中的可回收资源。

生命周期:守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。也就是说守护线程不依赖于终端,但是依赖于系统,与系统“同生共死”。那Java的守护线程是什么样子的呢。当JVM中所有的线程都是守护线程的时候,JVM就可以退出了;如果还有一个或以上的非守护线程则JVM不会退出。

注意:
当主线程运行到子线程名.join()时,在子线程完成运行之前,这个子线程的父线程将一直被阻塞,直到子进程运行完毕,父进程才会继续执行

一般来讲:线程的join方法和setdaemon()方法是连用的,setdaemon是把子进程设置为守护进程,等到主进程完成之后子进程也强制完成(退出)
join()方法作用是让子进程完毕之后,主线程才往下执行.

队列常用方法:
Queue.qsize() 返回队列的大小
Queue.empty() 如果队列为空,返回True,反之False
Queue.full() 如果队列满了,返回True,反之False
Queue.full 与 maxsize 大小对应
Queue.get([block[, timeout]])获取队列,timeout等待时间
Queue.get_nowait() 相当Queue.get(False)
非阻塞 Queue.put(item) 写入队列,timeout等待时间
Queue.put_nowait(item) 相当Queue.put(item, False)
Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
Queue.join() 实际上意味着等到队列为空,再执行别的操作

注意:
Queue.put(item) 放进去一个内部计数器加一
Queue.get() 取出一个内部计数器不减一,除非与Queue.task_done()在一起连用

Queue.join():
阻塞调用线程,直到队列中的所有任务被处理掉。

只要有数据被加入队列,未完成的任务数就会增加。当消费者线程调用task_done()(意味着有消费者取得任务并完成任务),未完成的任务数就会减少。当未完成的任务数降到0,join()解除阻塞。

进程:
主进程的代码块执行完毕不代表主进程结束,会等待子进程完毕后再退出

你可能感兴趣的:(守护线程)