- 👑专栏内容:Java
- ⛪个人主页:子夜的星的主页
- 💕座右铭:前路未远,步履不停
目录
- 一、`Thread`的常见构造方法
- 二、`Thread` 的常见属性
- 三、`Thread`的常用方法
- 1、`start`方法
- 2、中断一个线程
- Ⅰ、通过共享标记
- Ⅱ、调用`interrupt()` 方法
- 3、等待一个线程
- 4、休眠当前线程
前面用了这么多次Thread
类,下面我们就来详细的看看Thread
类里面到底有什么。
Thread
类在Java中是用于管理线程的关键类,换句话说,每个线程都与一个唯一的Thread
对象相关联。以我们上面的例子为例,每个执行流都需要有一个对象来描述。
Thread
类的对象就是用来描述一个线程执行流的,JVM会将这些Thread
对象组织起来,用于线程调度和管理。
一、Thread
的常见构造方法
方法签名 | 说明 |
---|---|
Thread() | 创建线程对象 |
Thread(Runnable target) | 使用 Runnable 对象创建线程对象 |
Thread(String name) | 创建线程对象,并命名 |
Thread(Runnable target, String name) | 使用 Runnable 对象创建线程对象,并命名 |
Thread(ThreadGroup group, Runnable target) | 线程可以被用来分组管理,分好的组即为线程组。了解即可。 |
Thread t1 = new Thread();
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread("这是我的名字");
Thread t4 = new Thread(new MyRunnable(), "这是我的名字");
public static void main(String[] args) {
Thread thread = new Thread(()->{
while(true){
System.out.println("这是线程运行代码!");
}
},"myThread");
thread.start();
}
这是用上面的构造方法新建的线程,并且命名为:myThread
我们运行后,打开自己jkd
的bin
目录。
连接这个正在运行的类。点击线程,就看有看见这个被我们命名的线程正在运行。
因为main
方法已经执行完了。
二、Thread
的常见属性
属性 | 获取方法 | 说明 | 注意 |
---|---|---|---|
ID | getId() | 获取线程的唯一标识符 | 不同线程的ID不会重复 |
名称 | getName() | 获取线程的名称 | 调试工具常用 |
状态 | getState() | 获取线程的当前状态 | 状态表示线程当前所处的情况 |
优先级 | getPriority() | 获取线程的优先级 | 优先级高的线程理论上更容易被调度到 |
是否后台线程 | isDaemon() | 检查线程是否为后台线程 | JVM会在所有非后台线程结束后才结束运行 |
是否存活 | isAlive() | 检查线程是否存活 | 简单理解为run 方法是否运行结束 |
是否被中断 | isInterrupted() | 检查线程是否被中断 | 后面再聊 |
主要说一下后台线程和前台线程。
在Java中,线程可以分为两种类型:前台线程(也称为用户线程)和后台线程(也称为守护线程)。这两种线程之间有一些关键的区别:
-
前台线程(用户线程):
- 当Java程序启动时,默认情况下创建的线程都是前台线程。
- 前台线程的执行不会影响程序的结束。即使所有的前台线程执行完毕,程序仍然会继续运行,直到
main
方法完成。 - 主要用于执行程序的核心功能,它们的结束可能导致程序的结束。
-
后台线程(守护线程):
- 后台线程是通过
setDaemon(true)
方法设置的,它告诉JVM这个线程是一个后台线程。 - 当所有的前台线程执行完毕,无论后台线程是否执行完毕,JVM都会终止程序,即JVM在结束时会等待所有的前台线程执行完毕,但不会等待后台线程。
- 后台线程通常用于执行一些支持性工作,例如垃圾回收、定期任务等。
- 后台线程是通过
在Java中,通过setDaemon(true)
方法将线程设置为后台线程:
public static void main(String[] args) {
Thread thread = new Thread(() -> {
while(true){
System.out.println("hello thread!");
}
});
//设置成后台线程
thread.setDaemon(true);
thread.start();
}
需要注意的是,一旦线程启动,就无法将其设置为或从后台线程切换回前台线程。因此,设置线程为后台线程应在启动线程之前完成。
三、Thread
的常用方法
1、start
方法
start
方法是用于在系统中创建真正的线程。
该方法的调用实际上是调用系统的API完成线程的创建工作。start
方法本身的执行是瞬时完成的,它仅仅是告诉系统你要创建一个线程。一旦start
被调用,代码会立即继续执行start
后续的逻辑。在这个过程中,系统会异步地执行新线程的run
方法,使得新线程可以并行运行。
操作系统 = 内核 + 配套的程序。
内核是一个系统最核心的功能:对下管理好硬件设备,对上给各种程序提供稳定运行环境。
2、中断一个线程
中断一个线程目前常见的有以下两种方式:
- 通过共享的标记来进行沟通
- 调用
interrupt()
方法来通知
Ⅰ、通过共享标记
通过共享的标记的这种方法是在线程之间共享一个标志(一个布尔变量),线程定期检查这个标志以决定是否应该停止执行。
public class SharedFlagExample implements Runnable {
private volatile boolean running = true;
public void run() {
while (running) {
// 执行线程的操作
}
}
public void stopRunning() {
running = false;
}
}
running
是一个共享的标志。当需要停止线程时,调用 stopRunning
方法将 running
设置为 false
,线程将在下一次循环时停止执行。
Ⅱ、调用interrupt()
方法
public class InterruptExample implements Runnable {
public void run() {
try {
// 执行可能会被中断的操作
while (!Thread.currentThread().isInterrupted()) {
// ...
}
} catch (InterruptedException e) {
// 处理中断异常
} finally {
// 清理工作
}
}
}
注意事项
- 使用
interrupt()
方法中断线程时,目标线程不一定会在收到中断信号后立即停止执行。 - 线程应该在适当的时候检查中断标志,并在必要时进行清理工作。
- 不建议使用
Thread.stop()
方法来中断线程,因为它可能会导致线程资源泄漏等问题。
3、等待一个线程
等待线程是指让当前线程进入阻塞状态,直到满足特定条件后再继续执行。
Java 提供了多种方法来实现线程等待,包括:
wait()
方法:用于让当前线程等待另一个线程对其进行唤醒。
join()
方法:用于让当前线程等待另一个线程终止。
sleep()
方法:用于让当前线程休眠指定的时间。
public class WaitExample {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
synchronized (WaitExample.class) {
try {
WaitExample.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread 1 is awake!");
});
thread1.start();
Thread.sleep(1000);
synchronized (WaitExample.class) {
WaitExample.class.notify();
}
}
}
4、休眠当前线程
休眠当前线程是指让当前线程进入阻塞状态,并等待指定的时间后再继续执行。Java 提供了 Thread.sleep()
方法来实现线程休眠。
public class SleepExample {
public static void main(String[] args) throws InterruptedException {
System.out.println("Thread 开始");
Thread.sleep(1000);
System.out.println("Thread 结束");
}
}