Thread类及常见方法

 Thread类及常见方法

一、Thread的常见构造方法

方法说明
Thread()创建一个新的线程对象,但不指定执行任务。需要通过继承Thread类并重写run()方法来定义任务。

Thread(Runnable target)

创建一个线程对象,并指定一个实现了Runnable接口的任务。
Thread(String name)创建一个线程对象并指定线程名称,便于调试和日志记录。
Thread(Runnable target,String name)创建一个线程对象,指定执行任务和线程名称。

二、Thread的几个常见属性

属性

获取方法

IDgetId ()
名称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()方法中断时,会根据实际情况做出响应。

  1. 如果该线程正在执行低级别的可中断方法(如Thread.sleep()、Thread.join()或Object.wait()),则会解除阻塞并抛出InterruptedException异常。
  2. 否则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);  //一秒

Java 中的 `Thread` 提供了多种方法用于管理线程的生命周期和行为。以下是一些常用方法的详细说明: ### 启动线程 - **`start()`**:启动一个新的线程并执行其 `run()` 方法。调用此方法后,线程进入就绪状态,等待 CPU 调度[^1]。 ### 执行线程任务 - **`run()`**:定义线程的具体任务。通常需要重写该方法以实现自定义逻辑。如果直接调用 `run()` 方法,则不会创建新线程,而是在当前线程中执行。 ### 线程调度 - **`static void yield()`**:使当前正在执行的线程暂停执行,让出 CPU 给其他具有相同优先级的线程。这是一个静态方法,适用于当前线程[^1]。 - **`static void sleep(long millis)`**:使当前线程暂停执行指定的毫秒数。此方法常用于模拟延迟或控制线程执行频率。线程在睡眠期间不会释放锁。 ### 线程同步 - **`void join()`**:等待该线程终止后再继续执行当前线程。此方法可以确保当前线程在另一个线程完成后才继续执行。它还可以带参数,表示等待的时间限制[^1]。 ### 线程中断 - **`void interrupt()`**:中断线程。如果线程处于阻塞状态(如调用 `sleep()` 或 `wait()`),则会抛出 `InterruptedException` 异常;否则,线程将继续运行直到结束[^1]。 ### 线程属性 - **`void setDaemon(boolean on)`**:设置线程为守护线程或用户线程。守护线程通常用于后台服务,当所有用户线程结束后,JVM 会自动退出。此方法必须在线程启动前调用[^1]。 - **`void setPriority(int newPriority)`**:设置线程的优先级。优先级范围为 1 到 10,默认优先级为 5。高优先级线程更可能被调度执行,但具体行为依赖于操作系统和 JVM 实现[^1]。 ### 示例代码 以下是一个简单的示例,展示了如何使用 `start()`、`run()`、`sleep()` 和 `setDaemon()` 方法: ```java public class ThreadExample { public static void main(String[] args) { Thread t1 = new Thread(() -> { for (int i = 0; i < 5; i++) { try { Thread.sleep(1000); // 每隔一秒输出一次 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread 1: " + i); } }); Thread t2 = new Thread(() -> { for (int i = 0; i < 5; i++) { System.out.println("Thread 2: " + i); } }); t2.setDaemon(true); // 设置为守护线程 t1.start(); t2.start(); } } ``` ### 相关问题 1. 如何在 Java 中创建和启动一个线程? 2. `start()` 和 `run()` 方法的区别是什么? 3. `join()` 方法在多线程编程中的作用是什么? 4. 什么是守护线程?如何设置线程为守护线程? 5. `yield()` 和 `sleep()` 方法在控制线程调度时有何不同?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值