Files
2026-01-15 11:53:37 +08:00

5.6 KiB
Raw Permalink Blame History

线程基础

目录


线程概念

进程 vs 线程

// 进程:程序执行的基本单位
// - 有独立的内存空间
// - 进程间通信复杂

// 线程CPU 调度的基本单位
// - 共享进程的内存空间
// - 线程间通信简单

主线程 vs 子线程

// 主线程UI 线程)
// - 负责 UI 更新
// - 不能执行耗时操作
// - 阻塞会导致 ANR

// 子线程(工作线程)
// - 执行耗时操作
// - 不能直接更新 UI
// - 需要通过 Handler 更新 UI

线程创建

方式1继承 Thread

public class MyThread extends Thread {
    @Override
    public void run() {
        // 线程执行代码
        System.out.println("Thread running");
    }
}

// 使用
MyThread thread = new MyThread();
thread.start();

方式2实现 Runnable

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程执行代码
        System.out.println("Thread running");
    }
}

// 使用
Thread thread = new Thread(new MyRunnable());
thread.start();

方式3Lambda 表达式

Thread thread = new Thread(() -> {
    System.out.println("Thread running");
});
thread.start();

线程状态

线程状态转换

NEW → RUNNABLE → BLOCKED → WAITING → TIMED_WAITING → TERMINATED

状态说明

// NEW新建状态
Thread thread = new Thread();

// RUNNABLE可运行状态
thread.start();

// BLOCKED阻塞状态等待锁
synchronized (lock) {
    // 其他线程等待锁
}

// WAITING等待状态
thread.wait();
LockSupport.park();

// TIMED_WAITING超时等待
Thread.sleep(1000);
thread.wait(1000);

// TERMINATED终止状态
// 线程执行完毕

线程同步

synchronized

// 同步方法
public synchronized void method() {
    // 临界区代码
}

// 同步代码块
public void method() {
    synchronized (this) {
        // 临界区代码
    }
}

// 同步静态方法
public static synchronized void staticMethod() {
    // 临界区代码
}

Lock

// ReentrantLock
private Lock lock = new ReentrantLock();

public void method() {
    lock.lock();
    try {
        // 临界区代码
    } finally {
        lock.unlock();
    }
}

// ReadWriteLock
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private Lock readLock = readWriteLock.readLock();
private Lock writeLock = readWriteLock.writeLock();

volatile

// volatile保证可见性不保证原子性
private volatile boolean flag = false;

// 适用场景
// 1. 状态标志
// 2. 双重检查锁定

线程通信

wait/notify

// wait等待
synchronized (lock) {
    while (!condition) {
        lock.wait(); // 释放锁,等待通知
    }
}

// notify通知
synchronized (lock) {
    condition = true;
    lock.notify(); // 唤醒一个等待线程
    // lock.notifyAll(); // 唤醒所有等待线程
}

CountDownLatch

// CountDownLatch等待多个线程完成
CountDownLatch latch = new CountDownLatch(3);

// 线程中
latch.countDown();

// 主线程等待
latch.await();

CyclicBarrier

// CyclicBarrier多个线程等待到齐
CyclicBarrier barrier = new CyclicBarrier(3);

// 线程中
barrier.await();

线程安全

线程安全问题

// ❌ 问题:非线程安全
private int count = 0;

public void increment() {
    count++; // 非原子操作
}

// ✅ 解决:使用同步
private int count = 0;

public synchronized void increment() {
    count++;
}

线程安全集合

// ConcurrentHashMap线程安全的 HashMap
ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();

// CopyOnWriteArrayList线程安全的 ArrayList
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();

// BlockingQueue阻塞队列
BlockingQueue<String> queue = new LinkedBlockingQueue<>();

线程基础最佳实践

1. 避免在 UI 线程执行耗时操作

// ❌ 错误
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    loadDataFromNetwork(); // 阻塞 UI 线程
}

// ✅ 正确
new Thread(() -> {
    loadDataFromNetwork();
    runOnUiThread(() -> {
        updateUI();
    });
}).start();

2. 使用线程池

// 使用线程池管理线程
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(() -> {
    // 执行任务
});

3. 及时释放资源

@Override
protected void onDestroy() {
    super.onDestroy();
    // 停止线程
    if (thread != null) {
        thread.interrupt();
    }
}

面试常见问题

Q1: 线程和进程的区别?

答案:

  • 进程:程序执行的基本单位,有独立内存空间
  • 线程CPU 调度的基本单位,共享进程内存空间

Q2: 如何创建线程?

答案:

  1. 继承 Thread
  2. 实现 Runnable
  3. 使用 Lambda 表达式

Q3: 线程状态?

答案: NEW → RUNNABLE → BLOCKED → WAITING → TIMED_WAITING → TERMINATED

Q4: 线程同步方式?

答案:

  1. synchronized
  2. Lock
  3. volatile
  4. 原子类

Q5: wait 和 sleep 的区别?

答案:

  • wait:释放锁,需要 notify 唤醒
  • sleep:不释放锁,时间到自动唤醒

最后更新2024年