一张图读懂 Java 多线程

一、带着疑问看图

1)竞争对象的锁和竞争CPU资源以及竞争被唤醒html

2)何种状况下获取到了锁,何种状况下会释放锁java

二、仍是那张图

2881047d559

三、详细图解

1)Thread t = new Thread(),初始化一个线程,实际上就是一个普通对象,此时他的状态为New学习

2)t.start(); 线程处于就绪状态(可运行状态),也就是随时等待着运行, 不要小看这个start,这个start决定了他是不是一个真正的线程实例,由于start为其准备了线程环境,你若只是普通调用run方法,那么这就是 一个普通的方法。处在这个时候的线程,都会去竞争CPU资源,因此谁被竞争到了CPU资源,也就是被调度Scheduler,那么他就能够从可运行状态到 真正运行状态。spa

3)当线程获取到了CPU资源时,线程就从可运行状态到真正运行状态,也就是Running,不用怀疑,他如今正在运行。操作系统

4)若是这个线程正在等待客户输入学习,也就是IO异常,等各类阻塞事件,也有多是本身调用了sleep等阻塞事件,线程就会从运行状态转为阻塞状态,这个状态是不会发生任何事情的!.net

5)一旦阻塞事件被清除,好比用户已经输入完成,IO流已经关闭,sleep也已经超时等,线程从阻塞状态变为就绪状态,又一次回到了可运行状态,随时与别的线程竞争资源,等待运行!线程

6)处于运行状态的线程可能会在运行当中遇到了同步方法或同步块,也就是synchronized标记的方法或块,这个时候该线程获到了对象的锁, 其余线程就没法进入该同步方法,那么这些没法执行的线程怎么办呢?他们就都阻塞在这里,等待锁的释放,重新去竞争锁资源,由于只有拥有锁的线程才有资格继 续往下运行,那么这里这些线程就阻塞在锁池(Lock Pool)。code

7)一旦被阻塞在锁池的线程竞争到了锁(以前的线程运行完了或以前的线程在内部跑出来异常,或者调用了wait等,都会释放线程的锁),那么这个线 程就会从阻塞状态转为就绪状态,不要觉得这个线程会马上执行,这是不可能的,你要想到线程执行都是要获取到CPU资源的,若是没有操做系统的调度,他们都 没有资格运行!orm

8)处于运行状态的线程可能会在运行当中进入了同步方法或同步块,这个时候他拥有了对象的锁,至高无上,但是因为当前环境可能致使他不必继续执 行,因此他会本身让出锁资源让别的线程也有机会继续执行,因此这个线程可能在synchronized内部调用所对象的wait方法,一旦调用,当前线程 让出锁资源,同时本身进入等待池(wait pool)中,直到被别的线程唤醒!若是没有被唤醒就一直会处在等待池当中,受到线程的阻塞,因此这个时候他们一心想要的是被唤醒,由于只有唤醒才有可能 继续运行!htm

9)一旦被阻塞在等待池的线程被唤醒(多是某个synchronized的线程调用了notify或notifyAll,也多是外部调用 interrupt致使内部抛出异常,也会获取到锁),那么这个线程就会从等待池转为锁池当中,继续阻塞,因此不要觉得线程被唤醒就会继续运行,这是不可 能的,他们一样须要竞争锁资源。

10)线程运行过程当中抛出异常,或者线程实在运行完了,那么线程就结束了,也就是消亡期。运行完了是不能够继续start的,必须重新new 一个线程才能start。那么将是有一个生命周期。

相关文章
相关标签/搜索