Java 多线程状态转换


线程基本状态图

    图中是线程运行的基本状态:线程调用start()方法开始后,就进入到可运行状态,随着CPU的资源调度在运行和可运行之间切换;遇到阻塞则进入阻塞状态。二三的状态图中只不过线程被阻塞的情况分为很多种,后面的图是细化说明。  

New --> Runnable

    当一个线程执行了start方法后,不代表这个线程就会立即被执行,只代表这个线程处于可运行的状态,最终由OS的线程调度来决定哪个可运行状态下的线程被执行。 

Running --> Runnable

  • Thread.yield()
  • 一个线程一次被选中执行是有时间限制的,这个时间段叫做CPU的时间片,当时间片用完但线程还没有结束时,这个线程又会变为可运行状态,等待OS的再次调度;

Running --> Blocked

  • 在一个运行中的线程等待用户输入
  • 调用Thread.sleep()
  • 调用了其他线程的join()方法

Blocked --> Runnable

  • 阻塞状态的线程用户输入完毕
  • sleep时间到
  • join的线程结束


同步的线程状态图

Lock pool --> Runnable

当资源被一个线程访问时,上锁,其他线程就进入了一个锁池(Lock pool)当锁被释放,其他线程获得了锁,就变为可运行状态。


加入线程间的相互作用  

               
  线程调用了wait()方法之后,释放掉锁,进入等待池(Wait pool) ;收到通知之后等待获取锁,获取锁之后才可以运行。

 

线程被阻塞可能是由于下面五方面的原因:(《Thinking in Java》)

1.调用sleep(毫秒数),使线程进入睡眠状态。在规定时间内,这个线程是不会运行的。

2.用suspend()暂停了线程的执行。除非收到resume()消息,否则不会返回“可运行”状态。

3.用wait()暂停了线程的执行。除非线程收到notify()或notifyAll()消息,否则不会变成“可运行”状态。

4.线程正在等候一些IO操作完成。

5.线程试图调用另一个对象的“同步”方法,但那个对象处于锁定状态,暂时无法使用。


线程同步各个方法的区别

  • Thread.yield()当前运行的线程变成可运行状态。
  • t2.join() 使得当前线程处于阻塞状态直到t2线程执行完毕。
  • Thread.sleep()使得当前线程处于阻塞状态直到sleep的时间结束。
  • wait、notify、notifyAll方法是Object类的方法,其调用环境必须有synchronized的同步块中调用,否则会抛java.lang.IllegalMonitorStateException异常。

 

发布了46 篇原创文章 · 获赞 35 · 访问量 34万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章