【Java多线程】【Thread类及常见方法】

本文详细介绍了Java中的Thread类,包括线程的创建、常见构造方法、线程属性如ID、名称、状态和优先级。讨论了如何通过sleep()方法使线程休眠,以及如何通过start()启动线程和interrupt()方法中断线程。此外,还解释了中断标志位的作用和为何会被清空,以及join()方法在线程同步中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1、定义

2、Thread常见 构造方法

 3、Thread 的常见属性

3、休眠线程 sleep()

 4、启动与中断线程

 4.1 start()

 4.2 中断线程

4.2.1  设置结束标志位

 4.2.2 interrupt() 方法

4.2.3  终止线程

 4.2.4 为什么会清空中断标志位?

 5、等待结束线程 —— join()


1、定义

  1. Thread类是 JVM用来管理线程的一个类,每个线程都有一个唯一的相关联的Thread对象;
  2. 每个执行流需要一个对象描述,就是Thread类的对象,JVM讲这些Thread对象组织起来,用于线程调度,线程管理;

2、Thread常见 构造方法

方法

功能

Thread()

创建线程对象

Thread(Runnable target)

使用 Runnable 对象创建线程对象

Thread(String name)

创建线程对象,并命名

Thread(Runnable target, String name)

使用 Runnable 对象创建线程对象,并命名

Thread(ThreadGroup group,

Runnable target)

线程可以被用来分组管理,分好的组即为线程组

代码:

 public static void main(String[] args) {
        Thread thread = new Thread(()->{
            System.out.println("Thread()构造方法");
        });
        thread.start();
    }
}
public static void main(String[] args) {
        Thread thread = new Thread(()->{
            System.out.println("Thread(String name)构造方法");
        },"线程 1");
        thread.start();
    }

 

 3、Thread 的常见属性

属性

获取方法

id

getId()

名称

getName()

状态

getState()

优先级

getPriority()

是否后台线程

isDaemon()

是否存活

isAlive()

是否被中断

isInterrupted()

 每个线程,都有自己的 状态、优先级、上下文、记账信息

  1. ID:是线程的唯一标识,不同线程不会重复;
  2. 名称:获取线程的命名,多用于调试
  3. 状态:表示线程当前所处的一个情况,下面会着重介绍
  4. 优先级:优先级高的线程 更容易被调度到(取值:1~10, 1最低,10最高)
  5. 后台: 后台被守护线程,isDaemon()判断,true为后台线程,false为前台线程
  • 线程被创建默认前台线程,前台线程会阻止JVM的退出
  • 后台线程不会阻止JVM退出JVM会在一个进程的所有非后台线程结束后,才会结束运行
  1. 存活:run()方法是否结束运行,run()没运行 false,正在运行 true
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(()->{
            System.out.println("Thread(String name)构造方法");
            for (int i = 0; i < 5; i++) {
                System.out.println("活着那");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                  e.printStackTrace();
                }
            }
            System.out.println("啊!快死了");
        },"线程 1");
        System.out.println("是否存活:"+thread.isAlive());
        thread.start();
        System.out.println("ID: "+thread.getId());
        System.out.println("Name: "+thread.getName());
        System.out.println("状态:"+thread.getState());
        System.out.println("优先级:"+thread.getPriority());
        System.out.println("后台?:"+thread.isDaemon());
        System.out.println("是否存活:"+thread.isAlive());
        Thread.sleep(10000);
        System.out.println("是否存活:"+thread.isAlive());
    }
}

3、休眠线程 sleep()

方法

功能

public static void sleep(long millis) throws InterruptedException

休眠当前线程 millis毫秒

 Thread.sleep() 方法是 Thread类中的一个静态方法,用于使当前线程暂停指定时间(以毫秒为单位)

  1. 会使当前线程进入阻塞状态让当前线程暂定执行,让出CPU给其他线程执行,等待指定时间后恢复执行
  2. 在调用sleep()方法后,线程就是在睡眠时间,如果中断睡眠提前唤醒,就会抛出InterruptedException 异常,捕获后就会对线程中断进行处理;
  3. sleep() 方法并不是精确的定时器,因为它依赖于系统调度器和其他线程的状态,因此实际的休眠时间可能会比指定的时间略长或略短。

 4、启动与中断线程

 4.1 start()

 调用 start 方法, 才真的在操作系统的底层创建出一个线程,也是将线程启动

 4.2 中断线程

中断 就是字面意思,让一个线程停下来,线程终止

本质:让线程的 入口方法执行完毕

  1. 给线程设置结束标志位
  2. 调用 interrupt() 方法来通知

4.2.1  设置结束标志位

  public static boolean isQuit = false;
    public static void main(String[] args) {
        Thread thread = new Thread(()->{
            while (!isQuit){
                System.out.println("活着那");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("啊!要死了");
        });
        thread.start();
        //主线程  修改 isQuit
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //设置isQuit true 终止线程
        isQuit = true;
    }

注意:

要将标志位设置为静态变量,因为lambda捕获变量必须是final修饰或未被改变的变量

 4.2.2 interrupt() 方法

终止线程就是 创建变量来控制循环来结束线程,Thread类 内置类一个标志位,作为线程是否被中断的标记.

方法

功能

public void interrupt()

中断当前或指定线程的执行,将中断标志置为true,表示线程已经被中断

public boolean isInterrupted()

用于检查当前线程是否被中断

public static void main(String[] args) {
    Thread thread = new Thread(()->{
        System.out.println("开始活了");
        //currentThread() 返货线程对象 thread
        //isInterrupted thread对象里的 自带的标志位 默认false
        while (!Thread.currentThread().isInterrupted()){
            System.out.println("活着那");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("啊!要死了");
    });
    //创建线程
    thread.start();
    //运行 main主线程
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    //设置标志位 为true
    thread.interrupt();
}
  1. currentThread()方法 返货线程对象 thread
  2. isInterrupted()方法 thread对象里的 自带的标志位 默认false
  3. 调用 sleep() 和 wait() 方法会使线程进入阻塞状态,直到指定的时间到达或者被其他线程唤醒才会继续执行;
  4. 如果在阻塞期间调用了线程的 interrupt() 方法,则会抛出InterruptedException异常,并将线程的中断标志位设置为 false
  5. 这样可以让 线程在捕获异常后继续执行或退出;
  6. 清除中断标志位 的操作是由 JVM的内部实现所产生的;

4.2.3  终止线程

如果不在异常退出,那么线程会继续运行,interrupt() 方法只调用了一次,但 sleep() 和 wait() 方法清除中断标志位,如同电座开关是按钮式,将通路有回弹又打开了

public static void main(String[] args) {
    Thread thread = new Thread(()->{
        System.out.println("开始活了");
        //currentThread() 返货线程对象 thread
        //isInterrupted thread对象里的 自带的标志位 默认false
        while (!Thread.currentThread().isInterrupted()){
            System.out.println("活着那");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
                //退出循环
                break;
            }
        }
        System.out.println("啊!要死了");
    });

 4.2.4 为什么会清空中断标志位?

  1. 调用sleep()方法,线程中断(中断位置设置为true),会抛出异常并将中断标志位清空(设置为false)
  2. 如果不清空中断标志位,接下来的执行过程中,线程可能会受到中断影响,导致意外结果;清空标志位为了让线程自身能够对线程何时结束有一个明确的控制;
  3. Interrput()只是通知,不是“命令”,通知线程你该结束了,至于是否结束,立即还是等会由代码灵活控制;

 5、等待结束线程 —— join()

线程之间是并发执行的,操作系统对于线程的调度,是无序的;

无法判定两个线程谁先执行,谁后执行;同,结束也不确定;这很不好;

所以,有时候就要明确规定结束顺序,可以用线程等待解决;

方法

功能

public void join()

等待线程结束

public void join(long millis)

等待线程结束,最多等 millis 毫秒

 join()方法,让当前线程等待调用该方法的线程的结束后执行;当前线程暂时进入阻塞状态

public static void main(String[] args) throws InterruptedException {
    Thread thread1 = new Thread(()->{
        for (int i = 0; i < 3; i++) {
            System.out.println("thread1 执行");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("thread1 执行完毕");
    });

    thread1.start();
    //thread1 调用该方法
    //main 等待 thread1结束后执行
    thread1.join();

    System.out.println("hello main");
}
// thread1 执行
// thread1 执行完毕
// hello main

在哪个线程调用,该线程进入阻塞状态,等待其他线程结束后 退出阻塞继续执行

也有两种情况:

  1. 死等,其他线程不结束不执行
  2. 等待指定时间,到时间就退出等待,继续执行

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值