Java多线程状态详解以及sleep和wait的区别

对于线程的理解可以想象成每个人,就跟人一样每个人都是有状态的,比如这个人刚出生,刚睡醒,开始跑了,被绑住了,在等待,死亡都可以用来理解线程的状态。


Java多线程状态详解以及sleep和wait的区别


一、线程的六种状态

我们查看线程源码会发现线程的六大状态


  1. NEW 新建状态,就是线程在start方法没有执行前就属于NEW状态
  2. RUNNABLE 可以运行状态,线程启动了,等待CPU时间片的切换让其运行,等待资源调度
  3. BLOCKED 阻塞状态,使用synchronized或者lock时没有获得锁时该线程就是锁状态
  4. WAITING 等待状态,使用Thread.join()或者.wait()时,就进入了等待状态
  5. TIMED_WAITING 计时等待,也就是说设定了等待时间,sleep(时间),join(时间),wait(时间)
  6. TERMINATED 终止状态,线程中断或者停止运行的状态
<code>

public

class

Me

{

public

static

void

main

(

String[] args

)

{ System.

out

.println(

"hello world"

); } }/<code>

二、用代码测试这些状态是在什么情况下发生的

我们使用代码对线程的状态进行一步步的监控,来更加深入的理解线程状态的触发方式,用休眠主线程的方式不断地判断子线程的状态方式,对于wait()我们可以用一个新线程进行唤醒,这样就可以顺利进入到终止状态,关于锁状态,这里就没演示了,可以用多个线程调用同一个方法实现这个锁状态。

<code> 

public

class

ThreadState

{

public

static

void

main

(

String[] args

) throws InterruptedException

{ ThreadState threadState=

new

ThreadState(); Thread thread=

new

Thread(()->{ synchronized (threadState){

try

{

for

(

int

i=

0

;i<

10

;i++) {

if

(i==

0

){ Thread.sleep(

1000

); }

else

if

(i==

1

){ threadState.wait(); }

else

if

(i==

2

){ System.

out

.println(

"我复活了"

); } } }

catch

(InterruptedException e) { e.printStackTrace(); } } }); Thread thread2=

new

Thread(()->{ synchronized (threadState){ threadState.notify(); } }); System.

out

.println(

"新建状态:"

+thread.getState()); thread.start(); System.

out

.println(

"等待运行状态:"

+thread.getState()); Thread.sleep(

500

); System.

out

.println(

"计时等待状态:"

+thread.getState()); Thread.sleep(

1500

); System.

out

.println(

"等待状态:"

+thread.getState()); thread2.start(); Thread.sleep(

1000

); System.

out

.println(

"终止状态:"

+thread.getState()); } }/<code>

输出结果如下,可以清楚看到每种状态的输出结果

<code>新建状态:

NEW

等待运行状态:RUNNABLE 计时等待状态:TIMED_WAITING 等待状态:WAITING 我复活了 终止状态:TERMINATED/<code>

三、sleep和wait的区别


Java多线程状态详解以及sleep和wait的区别


  1. sleep和wait的显著区别就是sleep不会释放锁而wait会释放锁。
  2. sleep可以在任何地方使用,wait,notify,notifyAll只能在同步控制方法或者同步控制块使用

wati()和notify()可以用来干嘛呢?简单解释就是每个对象都有wait方法,比如有一个用户对象,然后有一个线程专门将用户对象里面的内容写入到数据库,这个用户对象是由另一个线程不断搜索查询过来的,所以是不固定的,有时候user对象是有值的有时候没有,如果我这个写数据库的线程每次都因为user对象没有值还在不断地运行那岂不是浪费资源码?这时候就可以判断后使用wait让这个线程处于等待状态,另一个线程将user信息写入完成后在唤醒这个写数据库的线程,当然这种应用场景会很多,这里只是简单举例。


Java多线程状态详解以及sleep和wait的区别


那sleep可以让一个线程休眠从而让出CPU资源取调度其他线程,不会释放锁,也就是其他线程不能调用被sleep的方法块,除非sleep时间失效。

对于面试多线程也经常会问到sleep和wait的区别,如果不仔细研究的确会一脸懵逼,但确实有显著差别

四、wait和notify以及notifyAll的联系


Java多线程状态详解以及sleep和wait的区别


wait是让一个对象等待,notify就是将等待该对象的线程唤醒,notifyAll则是唤醒所有等待该对象的线程


分享到:


相關文章: