Java 多线程编程涉及许多重要的概念和思想,以下是一些关键点:
1. 线程(Thread)
线程是程序执行的最小单位。Java 提供了 Thread
类和 Runnable
接口来创建和管理线程。
2. 线程生命周期
线程有以下几种状态:
新建(New): 线程对象被创建,但尚未启动。
就绪(Runnable): 线程已经启动,等待 CPU 调度。
运行(Running): 线程正在执行。
阻塞(Blocked): 线程被阻塞,等待某个条件满足。
等待(Waiting): 线程等待另一个线程的通知或时间到期。
计时等待(Timed Waiting): 线程在指定时间内等待。
终止(Terminated): 线程执行完毕或被中断。
3. 同步(Synchronization)
同步用于控制多个线程对共享资源的访问,以避免数据不一致。Java 提供了 synchronized
关键字和 Lock
接口来实现同步。
4. 互斥锁(Mutex)
互斥锁用于确保同一时间只有一个线程可以访问共享资源。Java 的 synchronized
块和 ReentrantLock
类都可以实现互斥锁。
5. 死锁(Deadlock)
死锁是指两个或多个线程互相等待对方释放资源,导致所有线程都无法继续执行。避免死锁的方法包括资源排序、超时等。
6. 线程通信
线程之间可以通过 wait()
, notify()
, 和 notifyAll()
方法进行通信。这些方法必须在同步块或同步方法中调用。
7. 线程池(Thread Pool)
线程池用于管理和复用一组线程,减少线程创建和销毁的开销。Java 提供了 Executor
框架来实现线程池。
8. 并发集合(Concurrent Collections)
Java 提供了一些线程安全的集合类,如 ConcurrentHashMap
, CopyOnWriteArrayList
等,用于在多线程环境中安全地操作集合。
9. 原子操作(Atomic Operations)
Java 提供了 java.util.concurrent.atomic
包中的类,如 AtomicInteger
, AtomicBoolean
等,支持原子操作,避免使用锁。
10. 并发工具类
Java 提供了一些并发工具类,如 CountDownLatch
, CyclicBarrier
, Semaphore
, Exchanger
等,用于实现复杂的线程同步。
示例代码
以下是一个简单的多线程示例,展示了如何创建和启动线程,以及使用 synchronized
关键字进行同步:
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
class MyThread extends Thread {
private Counter counter;
public MyThread(Counter counter) {
this.counter = counter;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
Thread t1 = new MyThread(counter);
Thread t2 = new MyThread(counter);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Final count: " + counter.getCount());
}
}
在这个示例中,Counter
类使用 synchronized
关键字确保 increment
和 getCount
方法是线程安全的。两个线程 t1
和 t2
同时对 Counter
对象进行操作,最终结果是线程安全的。