目录
继承Thread类
扩展小知识:
Thread类的常见方法
Thread 类的静态方法
实现Runnable接口
使用Callable和Future创建线程
使用Executor框架创建线程池
为了更好地理解单线程和多线程的执行过程,接下来通过一个图例分析一下单线程和多线程的区别。
从上图可以看出,单线程的程序在运行时,会按照代码的调用顺序执行,而在多线程中,main()方法和MyThread类的run()方法却可以同时运行,互不影响,这正是单线程和多线程的区别。
示例代码如下:
class MyThread extends Thread {
public void run() {
// 线程执行的代码逻辑
System.out.println(Thread.currentThread().getName() +"线程正在运行");
}
}
public class Main {
public static void main(String[] args) {
// 创建线程并启动
MyThread thread = new MyThread();
thread.start();
System.out.println(Thread.currentThread().getName() + " main()方法执行结束");
}
}
运行结果:
main main()方法执行结束
Thread-0线程正在运行
currentThread() 是 Thread 类的静态方法,它返回当前正在执行的线程对象。具体来说,它返回一个表示当前线程的 Thread 对象。
可以使用 Thread.currentThread() 来获取当前线程的引用。这个方法常用于需要获得当前执行线程对象的场景,例如需要在运行时获取线程的名称、线程优先级、判断线程是否被中断等操作。
注意:currentThread() 是 Thread 类的静态方法,因此可以直接通过 Thread.currentThread() 的方式调用,不需要创建 Thread 对象实例。
下面是一个示例代码,演示如何使用 currentThread() 方法:
public class Main {
public static void main(String[] args) {
// 获取当前线程对象
Thread currentThread = Thread.currentThread();
// 获取当前线程的名称
String threadName = currentThread.getName();
System.out.println("当前线程名称:" + threadName);//当前线程名称:main
// 获取当前线程的优先级
int threadPriority = currentThread.getPriority();
System.out.println("当前线程优先级:" + threadPriority);//当前线程优先级:5
// 判断当前线程是否被中断
boolean isInterrupted = currentThread.interrupted();
System.out.println("当前线程是否被中断:" + isInterrupted);//当前线程是否被中断:false
}
}
注意:getPriority() 方法是 Thread 类的实例方法,用于获取线程的优先级。该方法返回一个表示线程优先级的整数值。
线程优先级的范围是从 1 到 10,默认优先级为 5。较大的优先级值意味着线程更重要或更紧急,但并不保证高优先级的线程总是比低优先级的线程先执行。
注意,实现 Runnable 接口相比直接继承 Thread 类具有更好的灵活性和可扩展性,因为它允许多个线程共享相同的 Runnable 实例。
下面是一个实现 Runnable 接口的示例代码:
class MyRunnable implements Runnable {
@Override
public void run() {
// 在此处添加想要线程执行的代码逻辑
System.out.println("线程运行中");
}
}
public class Main {
public static void main(String[] args) {
// 创建 MyRunnable 实例
MyRunnable myRunnable = new MyRunnable();
// 创建 Thread 对象并传入 MyRunnable 实例
Thread thread = new Thread(myRunnable);
// 启动线程
thread.start();
}
}
注意:使用 Callable 和 Future 创建线程相比直接使用 Runnable 接口和 Thread 类更为灵活,因为它允许获得线程的执行结果,并能够异步地处理任务。
下面是使用 Callable 和 Future 创建线程的示例代码:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main implements Callable {
@Override
public String call() {
// 在此处添加想要线程执行的代码逻辑
return "线程运行结束";
}
public static void main(String[] args) throws Exception {
// 创建 CallableExample 实例
Main callableExample = new Main();
// 创建线程池
ExecutorService executor = Executors.newSingleThreadExecutor();
// 提交 CallableExample 实例到线程池并返回 Future 对象
Future future = executor.submit(callableExample);
// 关闭线程池(可选)
executor.shutdown();
// 获取线程执行结果
String result = future.get();
System.out.println("线程结果: " + result);//线程结果: 线程运行结束
}
}
Executors提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。
主要有newFixedThreadPool,newCachedThreadPool,newSingleThreadExecutor,newScheduledThreadPool。
注意,调用 shutdown() 方法后,线程池将不再接受新的任务,并且会等待已提交的任务执行完成。
使用 Executor 框架可以更方便地管理和控制线程池,避免手动创建和启动线程的繁琐操作。
下面是使用 Executor 框架创建线程池的示例代码:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
// 创建固定大小的线程池,最多同时执行两个线程
ExecutorService executor = Executors.newFixedThreadPool(2);
// 提交任务到线程池
executor.submit(new MyTask("任务1"));
executor.submit(new MyTask("任务2"));
executor.submit(new MyTask("任务3"));
// 关闭线程池
executor.shutdown();
}
static class MyTask implements Runnable {
private String name;
public MyTask(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println("任务 " + name + " 正在执行");
}
}
}
执行结果
任务 任务2 正在执行
任务 任务1 正在执行
任务 任务3 正在执行