4.1.4.1.
线程生命周期(状态)
当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。
在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、阻塞
(Blocked)和死亡(Dead)5 种状态。尤其是当线程启动以后,它不可能一直"霸占"着 CPU 独自运行,所以 CPU 需要在多条线程之间切换,于是线程状态也会多次在运行、阻塞之间切换
1. 新建状态(NEW)
当程序使用 new 关键字创建了一个线程之后,该线程就处于新建状态,此时仅由 JVM 为其分配内存,并初始化其成员变量的值;
4.1.4.2.
就绪状态(RUNNABLE):
当线程对象调用了 start()方法之后,该线程处于就绪状态。Java 虚拟机会为其创建方法调用栈和程序计数器,等待调度运行。
4.1.4.3.
运行状态(RUNNING):
如果处于就绪状态的线程获得了 CPU,开始执行 run()方法的线程执行体,则该线程处于运行状态。
4.1.4.4.
阻塞状态(BLOCKED):
阻塞状态是指线程因为某种原因放弃了 cpu 使用权,也即让出了 cputimeslice,暂时停止运行。
直到线程进入可运行(runnable)状态,才有机会再次获得 cpu timeslice 转到运行(running)状态。阻塞的情况分三种:
等待阻塞(o.wait->等待对列):
运行(running)的线程执行 o.wait()方法,JVM 会把该线程放入等待队列(waitting queue)中。
同步阻塞(lock->锁池)
运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则 JVM 会把该线程放入锁池(lock pool)中。
其他阻塞(sleep/join)
运行(running)的线程执行 Thread.sleep(long ms)或 t.join()方法,或者发出了 I/O 请求时,JVM 会把该线程置为阻塞状态。当 sleep()状态超时、join()等待线程终止或者超时、或者 I/O
处理完毕时,线程重新转入可运行(runnable)状态。
4.1.4.5.
线程死亡(DEAD)
线程会以下面三种方式结束,结束后就是死亡状态。
正常结束
1. run()或 call()方法执行完成,线程正常结束。
异常结束
2. 线程抛出一个未捕获的 Exception 或 Error。
调用 stop
3. 直接调用该线程的 stop()方法来结束该线程—该方法通常容易导致死锁,不推荐使用。
4.1.6. sleep
与
wait
区别
1. 对于 sleep()方法,我们首先要知道该方法是属于 Thread 类中的。而 wait()方法,则是属于
Object 类中的。
13/04/2018
Page 62 of 283
2. sleep()方法导致了程序暂停执行指定的时间,让出 cpu 该其他线程,但是
他的监控状态依然
保持者
,当指定的时间到了又会自动恢复运行状态。
3. 在调用 sleep()方法的过程中,
线程不会释放对象锁
。
4. 而当
调用 wait()方法的时候,线程会放弃对象锁
,进入等待此对象的
等待锁定池
,只有针对此
对象调用 notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态
4.1.7. start
与
run
区别
1.
start()
方法来启动线程,真正实现了多线程运行。这时无需等待 run 方法体代码执行完毕,
可以直接继续执行下面的代码。
2. 通过调用 Thread 类的 start()方法来启动一个线程, 这时此线程是处于
就绪状态
, 并没有运
行。
3. 方法 run()称为线程体,它包含了要执行的这个线程的内容,线程就进入了
运行状态,开始运
行 run 函数当中的代码
。 Run 方法运行结束, 此线程终止。然后 CPU 再调度其它线程。
4.1.8. JAVA
后台线程
1. 定义:守护线程--也称“服务线程”,他是后台线程,它有一个特性,即
为用户线程 提供 公
共服务
,在没有用户线程可服务时会自动离开。
2. 优先级:守护线程的
优先级比较低
,用于为系统中的其它对象和线程提供服务。
3. 设置:通过
setDaemon(true)
来设置线程为“守护线程”;将一个用户线程设置为守护线程
的方式是在 线程对象创建 之前 用线程对象的 setDaemon 方法。
4.
在 Daemon 线程中产生的新线程也是 Daemon 的
。
5.
线程则是 JVM 级别的
,以 Tomcat 为例,如果你在 Web 应用中启动一个线程,这个线程的
生命周期并不会和 Web 应用程序保持同步。也就是说,即使你
停止了 Web 应用,这个线程
依旧是活跃的
。
6. example: 垃圾回收线程就是一个经典的守护线程,当我们的程序中不再有任何运行的Thread,
程序就不会再产生垃圾,垃圾回收器也就无事可做,
所以当垃圾回收线程是 JVM 上仅剩的线
程时,垃圾回收线程会自动离开
。它始终在低级别的状态中运行,用于实时监控和管理系统
中的可回收资源。
7. 生命周期:守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且周
期性地执行某种任务或等待处理某些发生的事件。也就是说守护线程不依赖于终端,但是依
赖于系统,与系统“同生共死”。当 JVM 中所有的线程都是守护线程的时候,JVM 就可以退
出了;如果还有一个或以上的非守护线程则 JVM 不会退出。
4.1.10.
线程基本方法
线程相关的基本方法有 wait,notify,notifyAll,sleep,join,yield 等
4.1.11.1.
进程
(有时候也称做任务)是指一个程序运行的实例。在 Linux 系统中,线程就是能并行运行并且
与他们的父进程(创建他们的进程)共享同一地址空间(一段内存区域)和其他资源的轻量
级的进程。