java 多线程的状态迁移 常用线程方法分析
一、线程的各个状态
图中的线程状态(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