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

本文详细解析Java线程的6种状态——初始、运行、阻塞、等待、超时等待和终止,以及关键线程方法如sleep(), yield(), join()等的使用和原理。了解线程生命周期管理,提升并发编程实践理解。
摘要由CSDN通过智能技术生成

线程状态

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

  1. 初始(NEW):新创建一个线程对象,但还没有调用start()方法。
  2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
    线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被CPU调度,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
  3. 阻塞(BLOCKED):表示线程阻塞于锁。
  4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
  5. 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
  6. 终止(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;
                }
                /*if (Thread.interrupted()) {
                    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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值