一、线程基础

在 Java 中创建线程有三种方式:

// 方式一:继承 Thread 类
public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程运行中...");
    }
}
new MyThread().start();

// 方式二:实现 Runnable 接口
new Thread(() -> {
    System.out.println("Lambda 方式创建线程");
}).start();

// 方式三:实现 Callable 接口(有返回值)
FutureTask<String> task = new FutureTask<>(() -> "结果");
new Thread(task).start();
String result = task.get();

二、线程池

频繁创建销毁线程开销很大,线程池通过复用线程来提升性能。推荐使用 ThreadPoolExecutor 手动创建:

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    5,                        // 核心线程数
    10,                       // 最大线程数
    60L, TimeUnit.SECONDS,    // 空闲线程存活时间
    new LinkedBlockingQueue<>(100),  // 任务队列
    new ThreadPoolExecutor.CallerRunsPolicy()  // 拒绝策略
);

executor.execute(() -> {
    System.out.println("执行任务");
});

executor.shutdown();  // 优雅关闭
参数说明
corePoolSize核心线程数,即使空闲也不回收
maximumPoolSize最大线程数
keepAliveTime非核心线程空闲存活时间
workQueue任务队列,缓存待执行的任务
handler拒绝策略:Abort(抛异常)、CallerRuns(调用者执行)、Discard(丢弃)、DiscardOldest(丢弃最旧)

三、锁机制

1. synchronized

// 同步方法
public synchronized void method() { }

// 同步代码块
synchronized (obj) {
    // 临界区代码
}

2. Lock 接口

private final ReentrantLock lock = new ReentrantLock();

public void method() {
    lock.lock();
    try {
        // 临界区
    } finally {
        lock.unlock();  // 必须在 finally 中释放
    }
}
特性synchronizedReentrantLock
获取锁方式阻塞等待可尝试非阻塞获取(tryLock)
公平性非公平可选公平/非公平
可中断不可中断可中断等待(lockInterruptibly)
条件变量wait/notifyCondition(可多条件)

四、JUC 常用工具类

  • CountDownLatch:等待一组线程完成后再继续
  • CyclicBarrier:多个线程互相等待,到达屏障后一起执行
  • Semaphore:控制同时访问资源的线程数量
  • ConcurrentHashMap:线程安全的 HashMap,分段锁实现
  • CopyOnWriteArrayList:写时复制,适合读多写少场景
// CountDownLatch 示例
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
    new Thread(() -> {
        // 执行任务
        latch.countDown();
    }).start();
}
latch.await();  // 等待三个线程全部完成
System.out.println("所有任务完成");

五、总结

并发编程的核心是正确地管理共享资源。记住:优先使用并发工具类而非底层锁,正确使用线程池避免资源耗尽,编写并发代码时先保证正确性再优化性能。