java 多线程的状态迁移 常用线程方法分析

北城以北 提交于 2020-02-14 23:43:52

一、线程的各个状态

  图中的线程状态(Thread.Stat 中定义的Enum 名)NEW、RUNNABLE 、TERMINATED、WAITING、TIMED_WAITING 和BLOCKED 都能够通过Thread 类的getState 方法获取。

由图中可以看到:

1、sleep方法只有timed_waiting,是Thread的静态方法,可以通过Thread类名调用,也可以用线程对象调用,执行sleep方法不释放锁,只让出CPU等待,是给其他线程执行机会的最佳选择;

2、wait方法notify、notifyAll方法只能在加锁的代码synchronized(obj) 中使用,用被锁住的资源Object.wait()调用,wait()之后,释放对象锁,进入等待队列,被其他程序notify或者超时之后进入同步队列,去争夺锁。

3、I/O操作类似sleep,是不会释放锁

4、在线程thread2中调用thread1.join()方法,则thread2线程会等待thread1线程执行完毕后才会继续执行,等待过程不会释放锁。(可参考下文代码)

5、obj.notify()唤醒在此对象等待队列上等待的单个线程,选择是任意性的。notifyAll()唤醒在此对象等待队列上等待的所有线程

6、Thread.yield(),当前线程调用此方法,当前线程放弃获取的CPU时间片,但不释放锁资源,由运行状态立即变为就绪状态,让OS再次选择线程。作用:让相同优先级的线程轮流执行,但并不保证一定会轮流执行。实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。

 1 public class join_sync {
 2     public static void main(String[] args) {
 3         Object oo = new Object();
 4         MyThread1 t1 = new MyThread1("线程t1--");
 5         MyThread2 t2 = new MyThread2("线程t2--", oo,t1);
 6         MyThread3 t3 = new MyThread3("线程t3--",oo);
 7         t2.start(); //t2先启动获得锁
 8         t3.start(); //t3刚启动时不会获得锁,因为锁被t2占有,t2中执行到join()时,t2先等待t1执行,但是此时没有释放锁
 9         t1.start(); //t2中执行到join()时,t2先等待t1执行结束,t2继续执行
10     }
11 }
12 
13 class MyThread1 extends Thread{
14     private String name;
15     public MyThread1(String name){
16         this.name = name;
17     }
18     @Override
19     public void run() {
20             for(int i = 0; i < 20; i++){
21                 System.out.println(name + i);
22             }
23     }
24 }
25 
26 class MyThread2 extends Thread{
27     private String name;
28     private Object oo;
29     public Thread threadd;
30     public MyThread2(String name,Object oo,Thread threadd){
31         this.name = name;
32         this.oo = oo;
33         this.threadd = threadd;
34     }
35     @Override
36     public void run() {
37         synchronized (oo) {
38             for(int i = 0; i < 20; i++){
39                 System.out.println(name + i);
40                 if(i==10) {
41                     try {
42                         threadd.join();
43                     } catch (InterruptedException e) {
44                         e.printStackTrace();
45                     }
46                 }
47             }
48         }
49     }
50 }
51 
52 class MyThread3 extends Thread{
53     private String name;
54     private Object oo;
55     public MyThread3(String name,Object oo){
56         this.name = name;
57         this.oo = oo;
58     }
59     @Override
60     public void run() {
61         synchronized (oo) {
62             for(int i = 0; i < 20; i++){
63                 System.out.println(name + i);
64             }
65         }
66     }
67 }
线程t1--0
线程t2--0
线程t1--1
线程t2--1
线程t1--2
线程t2--2
线程t1--3
线程t2--3
线程t1--4
线程t2--4
线程t1--5
线程t2--5
线程t1--6
线程t2--6
线程t1--7
线程t2--7
线程t1--8
线程t2--8
线程t1--9
线程t2--9
线程t1--10
线程t2--10
线程t1--11
线程t1--12
线程t1--13
线程t1--14
线程t1--15
线程t1--16
线程t1--17
线程t1--18
线程t1--19
线程t2--11
线程t2--12
线程t2--13
线程t2--14
线程t2--15
线程t2--16
线程t2--17
线程t2--18
线程t2--19
线程t3--0
线程t3--1
线程t3--2
线程t3--3
线程t3--4
线程t3--5
线程t3--6
线程t3--7
线程t3--8
线程t3--9
线程t3--10
线程t3--11
线程t3--12
线程t3--13
线程t3--14
线程t3--15
线程t3--16
线程t3--17
线程t3--18
线程t3--19

 参考文献:https://blog.csdn.net/pange1991/article/details/53860651

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!