复习线程——状态和几个Thread方法

时间:2022-08-29 18:37:13

一、线程的状态

(参考文章:https://blog.csdn.net/a58220655/article/details/76695142)

状态介绍

复习线程——状态和几个Thread方法

复习线程——状态和几个Thread方法

 

新建(new):处于该状态的时间很短暂。已被分配了必须的系统资源,并执行了初始化。表示有资格获得CPU时间。调度器可以把该线程变为runnable或者blocked状态


就绪(Runnable):这种状态下只要调度器把时间片分配给线程,线程就能运行。处在这种状态就是可运行可不运行的状态


阻塞(Bolocked):线程能够运行,但有个条件阻止它的运行。当线程处于阻塞状态时,调度器将会忽略线程,不会分配给线程任何CPU时间(例如sleep)。只有重新进入了就绪状态,才有可能执行操作。


死亡(Dead):处于死亡状态的线程讲不再是可调度的,并且再也不会得到CPU时间。任务死亡的通常方式是从run()方法返回。

 

堵塞原因

一个任务进入阻塞状态,可能有如下原因:

1.sleep

2.wait(),知道线程得到了notify()或者notifyAll()消息,线程才会进入就绪状态。

3.任务在等待某个输入/输出完成

4.线程在试图在某个对象上调用其同步控制方法,但是对象锁不可用,因为另一个任务已经获取了这个锁。

 

 

二、join方法

(参考文章:https://www.cnblogs.com/lcplcpjava/p/6896904.html)

join方法的同步作用

Thread类中的join方法的主要作用就是同步,它可以使得线程之间的并行执行变为串行执行

join的意思是使得放弃当前线程的执行,并返回对应的线程:
如果程序在main线程中调用t1线程的join方法,则main线程放弃cpu控制权,并返回t1线程继续执行直到线程t1执行完毕
所以结果是t1线程执行完后,才到主线程执行,相当于在main线程中同步t1线程,t1执行完了,main线程才有执行的机会

总之就哪个线程调用join就执行哪个线程或者说返回哪个线程,其他线性要放弃cpu控制权。

 

 

带参数的join方法

join方法可以传递参数,如果程序在main线程中调用t1线程的join(10)表示main线程会等待t1线程10毫秒,10毫秒过去后,
 main线程和t1线程之间执行顺序由串行执行变为普通的并行执行。

 

所以,join方法中如果传入参数,则表示这样的意思:如果A线程中掉用B线程的join(10),则表示A线程会等待B线程执行10毫秒,10毫秒过后,A、B线程并行执行。需要注意的是,jdk规定,join(0)的意思不是A线程等待B线程0秒,而是A线程等待B线程无限时间,直到B线程执行完毕,即join(0)等价于join()。

 

 

join方法的原理

join方法的原理就是调用相应线程的wait方法进行等待操作的,例如A线程中调用了B线程的join方法,则相当于在A线程中调用了B线程的wait方法,当B线程执行完(或者到达等待时间),B线程会自动调用自身的notifyAll方法唤醒A线程,从而达到同步的目的。

 

 

注意

join方法必须在线程start方法调用之后调用才有意义。这个也很容易理解:如果一个线程都没有start,那它也就无法同步了。

所以下面这是没有意义的代码:

t1.join();
t1.start();

 

 

 三、yeld方法

yield方法:使当前线程从执行状态(运行状态)变为可执行态(就绪状态Runnable)。这是个Thread的static方法哦!

 

cpu会从众多的可执行态里选择,也就是说,当前也就是刚刚的那个线程还是有可能会被再次执行到的,并不是说一定会执行其他线程而该线程在下一次中不会执行到了。

用了yield方法后,该线程就会把CPU时间让掉,让其他或者自己的线程执行(也就是谁先抢到谁执行)

 

 

四、附加说明

sleep是Thread的native方法,也是个static的方法。调用该方法后,当前线程睡眠,进入阻塞,但不放锁!!这个要和wait方法区别开来

start后线程进入就绪状态而不是立刻执行,线程在睡眠和挂起(wait)中恢复的时候也会进入就绪状态哦。