欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

多线程——线程状态及线程常用方法

时间:2023-07-09
线程状态

Java中线程的状态分为6种。

初始(NEW):新创建一个线程对象,但还没有调用start()方法。运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被CPU调度,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。阻塞(BLOCKED):表示线程阻塞于锁。等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。终止(TERMINATED):表示该线程已经执行完毕。
线程状态及状态装换如下图所示
线程常用方法

1、sleep():让出CPU,拥有锁不释放锁(TImedWaiting),可在任意地方调用,不必非得在同步代码中 可以使调用线程睡眠相应的时间,睡足时间后便又回到可运行状态等待CPU调度。
2、yield():** netive静态方法,让出CPU,拥有锁不释放锁,并回到可运行状态(Ready),和其他可运行线程一起等待CPU调度**,可能CPU依旧会调用到该线程。
3、join():使当前线程进入等待状态(Waiting),等待调用线程执行完后才能继续运行,join(time):使得线程在预计时间后和当前线程并行执行(TimeWaiting)
4、wait(): 将当前线程锁释放并进入等待状态(Waiting),wait(time)进入等待状态(TimeWaiting),在等待时间内未被唤醒则自动醒来,防止永久等待,必须在同步方法中调用
5、notify() / notifyAll():唤醒某个(无法确定是哪个线程) / 所有等待中的线程
6、interrupt():打断某个线程(设置中断标志为true),但是不能打断正在竞争锁的线程,如果对调用sleep()、wait()、join()的线程设置标志位会抛异常InterruptedException,必须进行捕获处理。
7、如果想打断线程争抢锁(设置标志位),那么使用ReentrantLock,用锁对象调用lockInterruptibly(),如果有设置标志位则抛异常(InterruptedException)
8、isInterrupted():查询某线程是不是被打断过
9、interrupted():静态方法,当前线程是不是被打断过,如果打断过,并恢复打断标志位false
10、stop():直接暂停线程,释放所有锁,容易产生数据不一致问题,不建议使用(已过时方法)
11、suspend()、resume():暂停线程与恢复线程,容易产生数据不一致问题,不建议使用(已过时方法)

优雅的结束某线程

1、结合interrupt()与( isInterrupted()或interrupted() )方法:达到某条件便设置打断标志位,检查标志位为true结束。(不依赖线程中间状态,针对wait(),sleep()等抛出异常的情况在catch语句块中也可做标志位的检查)

public class ThreadTest { public static void main(String[] args) throws InterruptedException { Thread t = new Thread(() -> { while(true){ System.out.println("Thread is interrupted ! "); System.out.println(Thread.currentThread().isInterrupted()); if (Thread.currentThread().isInterrupted()) { break; } } }); t.start(); Thread.sleep(2000L); t.interrupt(); }}

2、使用Volatile实现优雅结束线程(不依赖于线程的中间状态,Volatile没有啥问题),这里的中间状态比如说:线程中执行装数据,必须装到好多个数据就暂停。但是针对wait()、sleep()等抛异常的情况无法校验running标志。

public class ThreadTest { private static volatile boolean running = true; private static void m() { System.out.println("m start"); while (running) { System.out.println("hello"); } System.out.println("m end!"); } public static void main(String[] args) throws InterruptedException { new Thread(Tets::m, "t1").start(); Thread.sleep(1000L); running = false; }}

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。