继承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完成即继续。

线程安全

当多个线程访问共享资源(变量、对象、文件等)时,若未正确同步,可能导致:

  • 竞态条件:结果依赖线程执行顺序。
  • 数据不一致:如脏读、不可重复读。
  • 死锁/活锁:现成互相等待或无法推进。

现成安全解决方案

  1. 无状态对象
    无共享数据:方法内局部变量不跨线程共享,天然线程安全。
public class Stateless {
    public int add(int a, int b) {
        return a + b; // 无成员变量,线程安全
    }
}
  1. 不可变对象
    对象一旦创建,状态不可修改。
public final class ImmutableObject {
    private final int value;
    public ImmutableObject(int value) {
        this.value = value;
    }
    public int getValue() { return value; }
}
  1. 线程封闭
    栈封闭:局部变量仅存在于线程栈中。
    ThreadLocal:为每个线程创建独立副本。
public class ThreadLocalExample {
    private static ThreadLocal<SimpleDateFormat> dateFormat =
        ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
}
  1. 同步代码块
    使用synchronized关键字锁定共享资源。
public class Counter {
    private int count = 0;
    public synchronized void increment() { count++; }
    public synchronized int getCount() { return count; }
}
  1. 显式锁(ReentrantLock)
    更灵活的锁机制,支持超时、可中断、公平锁。
public class Counter {
    private int count = 0;
    private final ReentrantLock lock = new ReentrantLock();
    
    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }
}
  1. 原子类(Atomic Classes)
    基于CAS(Compare-And-Swap)的无锁操作,适合计数器等场景。
public class AtomicCounter {
    private AtomicInteger count = new AtomicInteger(0);
    public void increment() { count.incrementAndGet(); }
}
  1. 并发容器
    使用ConcurrentHashMap、CopyOnWriteArrayList等线程安全容器。
Map<String, String> map = new ConcurrentHashMap<>();
List<String> list = new CopyOnWriteArrayList<>();
  1. 读写锁
    读操作共享,写操作互斥,提升读多写少场景的性能。
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();
        }
    }
}

博弈
2.5k 声望1.5k 粉丝

态度决定一切


« 上一篇
Java GC机制
下一篇 »
Paimon概述

引用和评论

0 条评论