一、继承Thread类
实现步骤:
1.继承Thread类
2.重写run()方法
3.创建线程对象并调用start()方法
示例:
class MyThread extends Thread {@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + ": " + i);try {Thread.sleep(500); // 模拟耗时操作} catch (InterruptedException e) {e.printStackTrace();}}}
}public class ThreadExample {public static void main(String[] args) {MyThread t1 = new MyThread();MyThread t2 = new MyThread();t1.start(); // 启动线程1t2.start(); // 启动线程2System.out.println("主线程继续执行...");}
}
注意事项:
- 直接调用run() 方法是普通方法调用,不会启动新线程
- 一个线程对象只能start()一次
二、实现Runnable接口
实现步骤:
1.实现Runnable接口
2.实现run方法
3.创建Thread对象 并传入Runnable实例
4.调用start()方法
示例:
class MyRunnable implements Runnable {@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + ": " + i);}}
}public class RunnableExample {public static void main(String[] args) {MyRunnable runnable = new MyRunnable();Thread t1 = new Thread(runnable, "线程A");Thread t2 = new Thread(runnable, "线程B");t1.start();t2.start();}
}
优势:
- 避免单继承限制
- 适合多个线程共享相同代码
- 更符合面向对象设计思想
三、实现Callable接口(带返回值)
步骤:
1.实现Callable接口
2.实现call()方法
3.创建FutureTask对象包装Callable
4.创建Thread对象并传入FutureTask
5.调用start()方法
6.通过FutureTask.get()获取返回值
import java.util.concurrent.*;class MyCallable implements Callable<Integer> {@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 1; i <= 100; i++) {sum += i;Thread.sleep(10);}return sum;}
}public class CallableExample {public static void main(String[] args) throws Exception {MyCallable callable = new MyCallable();FutureTask<Integer> futureTask = new FutureTask<>(callable);Thread t = new Thread(futureTask);t.start();// 主线程继续做其他工作System.out.println("主线程正在计算其他内容...");// 获取子线程计算结果(会阻塞直到计算完成)int result = futureTask.get();System.out.println("计算结果: " + result);}
}
特点:
- 可以获取线程执行结果
- call()方法可以抛出异常
- 支持泛型返回值
四、使用线程池(推荐方式)
实现步骤:
1.创建线程池
2.提交任务(Runnable/Callable)
3.关闭线程池
import java.util.concurrent.*;public class ThreadPoolExample {public static void main(String[] args) {// 创建固定大小的线程池ExecutorService executor = Executors.newFixedThreadPool(3);// 提交10个任务for (int i = 0; i < 10; i++) {final int taskId = i;executor.execute(() -> {System.out.println(Thread.currentThread().getName() + " 正在执行任务 " + taskId);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}});}// 关闭线程池executor.shutdown();try {// 等待所有任务完成if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {executor.shutdownNow();}} catch (InterruptedException e) {executor.shutdownNow();}}
}
线程池优势:
1.降低资源消耗:复用已创建的线程。
2.提高响应速度:任务到达时线程已存在
3.提高线程可管理性:统一分配、调优和监控
4.防止资源耗尽:通过限制线程数量
5.多线程编程注意事项
1.线程安全:注意共享资源的同步访问
2.避免死锁:按固定顺序获取多个锁
3.性能考量:线程创建和上下文切换有开销
4.资源释放:确保finally块中释放锁和IO资源
5.异常处理:子线程异常需特殊处理(可设置UncaughtExceptionHandler)