1. **继承 `Thread` 类**
创建并运行一个新的线程最直接的方式就是让自定义类去扩展 `java.lang.Thread` 类,并重写它的 `run()` 方法。该方法包含了实际要在线程中执行的操作:
java
class MyRunnable extends Thread {
@Override
public void run() {
// 这里编写要在新线程上执行的代码逻辑
}
}
public class Main {
public static void main(String[] args) {
MyRunnable thread = new MyRunnable();
thread.start(); // 此处调用 start() 来启动新的线程
}
}
2. **实现 `Runnable` 接口**
另一种创建线程的方法是创建一个实现了 Runnable 接口的对象,然后把这个对象作为参数传递给 Thread 构造函数来实例化一个 Thread 对象:
java
class Worker implements Runnable {
@Override
public void run() {
// 在这里添加需要异步执行的任务内容
}
}
public class Main {
public static void main(String[] args) {
Worker task = new Worker();
Thread myThread = new Thread(task);
myThread.start(); // 使用同样的start()方法启动线程
}
}
相比于继承 Thread 的方式,使用 Runnable 更有利于面向接口编程以及避免因单继承带来的局限性,同时可以方便地把同一个工作单元提交到不同的 ExecutorService 或者其他高级线程池框架进行复用或调度。
3. **Lambda 表达式配合 Callable 和 FutureTask (从 JDK8 开始)**
JDK 8 引入了 Lambda 表达式后,我们可以更为简洁高效地创建线程:
java
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class Main {
public static void main(String[] args) throws Exception{
Callable<String> worker = () -> "Hello from New Thread!";
FutureTask<String> futureTask = new FutureTask<>(worker);
Thread t = new Thread(futureTask);
t.start();
System.out.println("Main thread is waiting for result...");
String result = futureTask.get(); // 获取Callable返回的结果
System.out.println(result);
}
}
在此例中,我们不仅启用了新的线程,而且可以通过Future获取到了由Callable计算出的结果,在高阶应用如结果同步、异常控制等场景下尤为有用。
4. **Executor 框架**
Java 提供了一个强大的 Executors 工具类用于简化线程管理和提高性能效率。它可以生成预配置的不同类型的线程池,比如 FixedThreadPool, CachedThreadPool, ScheduledThreadPool 等,从而提供了一种更加灵活且功能丰富的线程构建策略:
java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
// 执行具体业务操作
});
// 关闭executor以释放系统资源
executor.shutdown();
}
}
以上四种方式展示了如何在 Java 应用中启动线程,开发者可以根据项目的实际情况选择最合适的方式来创建及管理工作负载,使得应用程序能充分利用现代硬件环境中的多核处理器优势,提升系统的整体响应速度和服务质量。