欢迎浏览高耳机的博客
希望我们彼此都有更好的收获
感谢三连支持!
在现代编程中,多线程是提高程序性能和响应能力的一种重要手段。Java 通过 Thread
类和 Runnable
接口提供了丰富的线程管理功能。本文是对 Thread
类基本用法的总结。
线程创建
线程可以通过继承 Thread
类或实现 Runnable
接口来创建。下面举例了五种常见的线程创建方式,其中继承 Thread
类的方式更直接,但一个类只能继承一个父类,因此推荐使用实现 Runnable
接口或者使用lambda表达式的方式。
//1.继承Thread类,重写run方法:
public static class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程运行中...");
}
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
}
//2.实现Runnable接口,重写run方法:
public static class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("线程运行中...");
}
}
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
//3.继承Thread类,重写run方法,使用匿名内部类:
public static void main(String[] args) {
Thread thread = new Thread() {
@Override
public void run() {
System.out.println("线程运行中...");
}
};
thread.start();
}
//4.实现Runnable接口,重写run方法,使用匿名内部类:
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程运行中...");
}
});
thread.start();
}
//5.使用Lambda表达式:
public static void main(String[] args) {
Thread thread = new Thread(() -> System.out.println("线程运行中..."));
thread.start();
}
值得注意的是,在Thread类中,run();和start();存在一定的区别和联系:
方法的区别:
1.run方法被直接调用时,会和其他普通方法一样在当前线程中直接执行;
2.start方法是Thread类一个特殊的方法,当调用start方法时,它会调用run方法并创建一个新的线程来执行;
运行结果的区别:
1.run方法是直接在当前线程中执行的,意味着它不会并行,而是按照顺序执行;
2.调用start方法,JVM会分配一个新的线程,并在这个新线程中调用run方法;使其可以和主线程进行并行;
线程中断
线程中断是一种协作机制,它提供了一种让线程通知其他线程结束运行的方式。可以通过调用线程的 interrupt();
方法来中断线程。
interrupt()方法:当调用一个线程的
interrupt()
方法时,会将该线程的中断标志设置为true
。isInterrupted()方法:此方法用于检查线程的中断标志是否为
true
。Thread.currentThread().isInterrupted()
用于检查当前线程的中断标志,而t.isInterrupted()
用于检查指定线程的中断标志。InterruptedException:当线程在阻塞状态(如调用
Thread.sleep()
、Object.wait()
等)时,如果该线程被中断,会抛出InterruptedException
异常,并且清除中断标志(即将其设置为false
)。
class MyThread extends Thread {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// 线程的工作
}
System.out.println("线程被中断");
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread();
t.start();
Thread.sleep(1000); // 等待一段时间
t.interrupt(); // 中断线程
}
}
线程等待
线程等待通常是指让当前线程暂停执行,直到其他线程完成某些操作。通过 join();
方法实现。
class MyThread extends Thread {
public void run() {
// 线程的工作
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
t1.start();
t1.join(); // 等待t1线程完成
t2.start();
}
}
试试看如果注释掉t1.join();会发生什么? 答案是t1与t2线程会同时执行工作,而从微观角度来看,它们的运行时间会有细微的差异,因此每次的运行输出结果可能会有所不同;
正是因为有了join等待机制,使得t2必须等待t1线程完成工作才得以运行,从而保证了输出结果的稳定性;
线程休眠
线程休眠是指让当前线程暂停执行一段时间,可以通过 Thread.sleep()
方法实现。
class MyThread extends Thread {
public void run() {
// 线程的工作
System.out.println("Thread " + Thread.currentThread().getName() + " is running.");
}
}
public class Main {
public static void main(String[] args) {
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
t1.start();
try {
// 主线程睡眠1000毫秒
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
在这个代码中,t1
线程会立即启动,而t2
线程会在主线程睡眠1000毫秒后启动。这样,t2
线程的启动时间会比t1
晚1000毫秒。这是在不修改MyThread
类的情况下,通过控制主线程的执行流程来实现t2
的延迟启动. 和使用join线程等待来实现输出顺序的稳定性有一定的相似之处.
获取线程实例
每个线程都是 Thread
类的实例。在创建线程时,无论是通过继承 Thread
类还是实现 Runnable
接口,都会创建一个 Thread
对象。
Thread t1 = new Thread(new MyRunnable());
在这个例子中,t1 就是线程的实例。
希望这篇博客能为你理解多线程并行提供一些帮助。
如有不足之处请多多指出。
我是高耳机。