继承Thread类
通过继承Thread类并重写run()方法实现线程逻辑。
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程执行: " + Thread.currentThread().getName());
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // 启动线程,调用 start() 而非 run()
}
}
特点:
- 简单直接,适合简单场景。
- 缺点:Java不支持多继承,继承Thread类后无法再继承其他类。
实现Runnable接口
通过实现Runnable接口的run()方法,将任务逻辑与线程分离。
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("线程执行: " + Thread.currentThread().getName());
}
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}
特点:
- 更灵活,避免单继承的限制。
- 推荐方法,适合任务与线程解耦的场景。
实现Callable接口+Future
通过Callable接口实现带返回值的线程任务,结合Future或FutureTask获取结果。
import java.util.concurrent.*;
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "任务完成: " + Thread.currentThread().getName();
}
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new MyCallable());
System.out.println(future.get()); // 阻塞直到任务完成
executor.shutdown();
}
}
特点:
- 支持返回值,可抛出异常。
- 配合线程池使用更高效。
使用线程池(ExecutorService)
通过线程池管理线程资源,避免频繁创建和销毁线程的开销。
import java.util.concurrent.*;
public class ThreadPoolDemo {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 0; i < 5; i++) {
executor.execute(() -> {
System.out.println("线程执行: " + Thread.currentThread().getName());
});
}
executor.shutdown(); // 关闭线程池
}
}
特点:
- 资源复用,提高性能。
- 支持任务队列、拒绝策略等高级配置。
基于Lambda表达式(简化写法)
Java8+支持用Lambda表达式简化Runnable或Callable的写法。
public class LambdaThread {
public static void main(String[] args) {
// Runnable 的 Lambda 简化
new Thread(() -> System.out.println("Lambda线程执行")).start();
// Callable 的 Lambda 简化
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(() -> "Lambda任务完成");
}
}
异步编程CompletableFuture
基于Future模式,支持非阻塞组合操作和函数式编程。其核心特性包括:
- 异步执行:任务提交后立即返回CompletableFuture对象。
- 链式调用:通过thenApply、thenCompose等方法串联多个操作。
- 组合操作:合并多个Future(如allOf、anyOf)。
- 异常处理:通过exceptionally或handle捕获异常。
任务提交:
CompletableFuture.supplyAsync(() -> "Hello", executor); // 带返回值 CompletableFuture.runAsync(() -> System.out.println("Run"), executor); // 无返回值
结果处理:
- thenApply:同步转换结果。
- thenApplyAsync:异步转换结果(使用默认或指定线程池)。
结果合并:
- thenCombine:合并两个Future的结果。
- thenCompose:串联两个Future(前一个结果作为下一个输入)。
组合多个Future:
- allOf:等待所有Future完成。
- anyOf:任意一个Future完成即继续。
线程安全
当多个线程访问共享资源(变量、对象、文件等)时,若未正确同步,可能导致:
- 竞态条件:结果依赖线程执行顺序。
- 数据不一致:如脏读、不可重复读。
- 死锁/活锁:现成互相等待或无法推进。
现成安全解决方案
- 无状态对象
无共享数据:方法内局部变量不跨线程共享,天然线程安全。
public class Stateless {
public int add(int a, int b) {
return a + b; // 无成员变量,线程安全
}
}
- 不可变对象
对象一旦创建,状态不可修改。
public final class ImmutableObject {
private final int value;
public ImmutableObject(int value) {
this.value = value;
}
public int getValue() { return value; }
}
- 线程封闭
栈封闭:局部变量仅存在于线程栈中。
ThreadLocal:为每个线程创建独立副本。
public class ThreadLocalExample {
private static ThreadLocal<SimpleDateFormat> dateFormat =
ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
}
- 同步代码块
使用synchronized关键字锁定共享资源。
public class Counter {
private int count = 0;
public synchronized void increment() { count++; }
public synchronized int getCount() { return count; }
}
- 显式锁(ReentrantLock)
更灵活的锁机制,支持超时、可中断、公平锁。
public class Counter {
private int count = 0;
private final ReentrantLock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
}
- 原子类(Atomic Classes)
基于CAS(Compare-And-Swap)的无锁操作,适合计数器等场景。
public class AtomicCounter {
private AtomicInteger count = new AtomicInteger(0);
public void increment() { count.incrementAndGet(); }
}
- 并发容器
使用ConcurrentHashMap、CopyOnWriteArrayList等线程安全容器。
Map<String, String> map = new ConcurrentHashMap<>();
List<String> list = new CopyOnWriteArrayList<>();
- 读写锁
读操作共享,写操作互斥,提升读多写少场景的性能。
public class CachedData {
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private Object data;
public void update(Object newData) {
rwl.writeLock().lock();
try {
data = newData;
} finally {
rwl.writeLock().unlock();
}
}
public Object read() {
rwl.readLock().lock();
try {
return data;
} finally {
rwl.readLock().unlock();
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。