来说说java中的线程吧

162 阅读3分钟

总共有六种状态
1.新创建(New)
2可运行(Runnable)
3被阻塞(Blocked)
4等待(waiting)
5计时等待(Time waiting)
6被终止
我们看线程状态可以通过getstate()方法来获取,任何时刻线程只能处于同一种状态。
NEW表示线程被创建但是还没有被启动状态,我们new Threa()新建一个线程时,如果线程还没有开始运行start()方法,那么线程也就没开始执行运行run方法里面的代码,那就是new状态,一旦调用start()方法就进入Runnable状态
Runnable状态:
java中Runnable有两种状态一种是Running另一种是Ready,分别是可能正在执行,也有可能没有正在执行,正在等待CPU分配资源。
所以如果一个正在运行的线程是Runnable状态,当线程运行到了一半的时候,执行该线程的CPU被调度去做其他事情,导致该线程暂时不运行,他的状态不改变,还是Runnable。
如何是阻塞态Blocked(被阻塞),waiting(等待),Time waiting(计时等待)都可以被称为阻塞状态。 被阻塞状态
从Runnable到Blocked状态只有一种途径那就是进入到synchronized代码块中未获取到monitor锁,(synchronized底层实现就是monitor锁)就变成了Blocked状态
等待状态
进入Waiting有三种方法
1.当线程中调用了没有设置Timeout参数中的Object。wait()方法
2.当线程调用了没有设置Timeout参数中的Threa.join方法
3.当线程调用了LockSupport.park()方法
线程除了进入synchronized这种锁是进入到被阻塞状态,进入其他锁都是到等待状态。
Blocked和Watting的区别
Blocked是等待其他线程释放monitor锁
Waiting是等待某个条件。比如join的线程执行完毕,或者是notify()、notifyALL()
计时等待状态
计时等待和等待非常相似,区别是在于是否有时间限制,在Time waiting状态时会等待超时,之后由系统唤醒,或者也可以提前被通知唤醒如notify。
有以下四种方法会进入到计时等待状态。
1.线程设置了时间参数的Thread.sleep(long millis)方法。
2.线程设置了时间参数的Object。wait(long timeout)方法;
3.线程设置了时间参数的Thread.join(long millis)方法。
4.线程设置了时间参数的LockSupport.parkNanos(long nanos)方法和LockSupport。parkUntil(long deadline)方法。
下面是进入到Runnable状态
Blocked状态
Blocked进入到Runnable状态是获取到了monitor锁,但是如果想进入其他状态不会主动进入的。 Waiting状态
waiting进入到Runnable:执行了LockSupport.unpark(),或者join线程运行结束,或者被中断才可以进入到Runnable状态
如果是其他线程调用notify或者notifyAll来唤醒他,则它会进入Blocked状态,为什么会进入这里是因为如果调用这两个方法,要求必须首先持有该monitor锁,也就是说wait(),notify必须在synchronized代码块中。
所以waiting状态的线程被唤醒时拿不到该锁,就会进入Blocked状态,直到执行了notify、notifyAll()唤醒它的线程执行完毕并释放monitor锁,才可能轮到它去抢夺这把锁,如果能抢到,就会从Blocked回到Runable状态。
Time Waiting状态
计时等待状态和等待状态进入到Runnable状态一样,执行notify、notifyAll()会先进入到Blocked状态,然后抢夺成功后,回到Runnable状态。
它存在超时机制,就是说如果时间到了那么就会系统自动直接拿到锁,或者当join线程执行结束、调用了LockSupport.unpark()/被中断都会进入Runnable状态,不会进入Blocked状态\

Terminated终止
Terminated状态进入这个状态有两种可能。
1.run方法执行完毕,线程正常退出。
2.出现没有捕获的异常,终止run方法。\