Thread类及常见方法
一、Thread的常见构造方法
方法 | 说明 |
Thread() | 创建一个新的线程对象,但不指定执行任务。需要通过继承Thread 类并重写run() 方法来定义任务。 |
Thread(Runnable target) | 创建一个线程对象,并指定一个实现了Runnable 接口的任务。 |
Thread(String name) | 创建一个线程对象并指定线程名称,便于调试和日志记录。 |
Thread(Runnable target,String name) | 创建一个线程对象,指定执行任务和线程名称。 |
二、Thread的几个常见属性
属性 |
获取方法 |
ID | getId () |
名称 | getName () |
状态 | getState () |
优先级 | getPriority () |
是否后台线程 | isDaemon () |
是否存活 | isAlive () |
是否被中断 | isInterrupted () |
- ID 是线程的唯一标识,不同线程不会重复
- 名称是各种调试工具用到
- 状态表示线程当前所处的一个情况,下面我们会进一步说明
- 优先级高的线程理论上来说更容易被调度到
- 关于后台线程,需要记住一点:JVM 会在一个进程的所有非后台线程结束后,才会结束运行。
- 是否存活,即简单的理解,为 run 方法是否运行结束了
三、启动一个线程--start()
调用start方法,才真的在操作系统的底层创建出⼀个线程。
thread.start();
四、中断一个线程
目前常见的有以下两种方式:
1. 通过共享的标记来进行沟通
使用自定义的变量来作为标志位,需要给标志位上加volatile关键字
2. 调用interrupt()方法来通知
每个线程都一个与之关联的布尔属性来表示其中断状态。
interrupt()
方法:这是
Thread
类的一个实例方法,作用是给指定线程设置中断标志位。当对一个线程调用interrupt()
方法时,并不会立即停止该线程的执行,只是将线程的中断标志位设置为true
。Thread thread = new Thread(() -> { // 线程执行的任务 }); thread.start(); // 给线程设置中断标志 thread.interrupt();
isInterrupted()
方法:同样是
Thread
类的实例方法,用于判断当前线程的中断标志位是否为true
,不会清除中断标志位。Thread thread = Thread.currentThread(); if (thread.isInterrupted()) { System.out.println("线程已被中断"); }
interrupted()
方法:这是
Thread
类的静态方法,用于判断当前线程是否被中断,与isInterrupted()
不同的是,调用interrupted()
方法会清除当前线程的中断标志位(将其设置为false
)。if (Thread.interrupted()) { System.out.println("线程被中断,且中断标志已清除"); }
调用 interrupt 是如何让线程抛出异常的?
每个线程都一个与之关联的布尔属性来表示其中断状态,中断状态的初始值为false,当一个线程被其它线程调用Thread.interrupt()方法中断时,会根据实际情况做出响应。
- 如果该线程正在执行低级别的可中断方法(如Thread.sleep()、Thread.join()或Object.wait()),则会解除阻塞并抛出InterruptedException异常。
- 否则Thread.interrupt()仅设置线程的中断状态,在该被中断的线程中稍后可通过轮询中断状态来决定是否要停止当前正在执行的任务。
五、等待一个线程-join()
方法 | 说明 |
public void join () | 等待线程结束 |
public void join (long millis) | 等待线程结束,最多等 millis 毫秒 |
public void join (long millis, int nanos) | 同理,但可以更高精度 |
六、获取当前线程引用
方法 | 说明 |
public static Thread currentThread(); | 返回当前线程对象的引用 |
public class ThreadDemo {
public static void main(String[] args) {
Thread thread = Thread.currentThread();
System.out.println(thread.getName());
}
}
七、休眠当前线程
因为线程的调度是不可控的,所以,这个方法只能保证 实际休眠时间是大于等于参数设置的休眠时间的。
以毫秒为单位
Thread.sleep(1000); //一秒