Java 并发编程涉及多线程、同步机制、锁、线程池等核心概念。理解这些概念是掌握并发编程的基础。多线程允许程序同时执行多个任务,提高效率。同步机制确保线程安全,避免数据竞争。锁用于控制对共享资源的访问,线程池管理线程的生命周期,减少资源开销。
Java 提供了多种创建线程的方式,包括继承 Thread
类和实现 Runnable
接口。推荐使用 Runnable
接口,因为它更灵活,避免了单继承的限制。线程的状态包括新建、就绪、运行、阻塞和终止。合理管理线程状态是并发编程的关键。
// 实现 Runnable 接口
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Thread is running");
}
}
// 启动线程
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}
Java 提供了多种同步机制,如 synchronized
关键字和 Lock
接口。synchronized
是内置锁,使用简单但功能有限。Lock
接口提供了更灵活的锁控制,如可中断锁、超时锁等。ReentrantLock
是 Lock
的常用实现类。
// 使用 synchronized
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
}
// 使用 ReentrantLock
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Counter {
private int count = 0;
private Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
}
线程池是管理线程的有效工具,可以减少线程创建和销毁的开销。Java 提供了 ExecutorService
接口及其实现类 ThreadPoolExecutor
来管理线程池。通过配置核心线程数、最大线程数和队列策略,可以优化线程池性能。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
executor.execute(new MyRunnable());
}
executor.shutdown();
}
}
Java 提供了一系列并发集合类,如 ConcurrentHashMap
、CopyOnWriteArrayList
等,这些类在多线程环境下提供了高效的线程安全操作。使用并发集合类可以避免手动同步带来的复杂性。
import java.util.concurrent.ConcurrentHashMap;
public class Main {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("key", 1);
System.out.println(map.get("key"));
}
}
Java 的 java.util.concurrent.atomic
包提供了原子操作类,如 AtomicInteger
、AtomicLong
等。这些类通过 CAS(Compare-And-Swap)操作实现无锁线程安全,适用于高并发场景。
import java.util.concurrent.atomic.AtomicInteger;
public class Counter {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet();
}
public int getCount() {
return count.get();
}
}
Java 提供了多种并发工具类,如 CountDownLatch
、CyclicBarrier
、Semaphore
等。这些工具类用于协调多个线程的执行顺序和资源访问,简化了复杂的并发场景实现。
import java.util.concurrent.CountDownLatch;
public class Main {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println("Thread finished");
latch.countDown();
}).start();
}
latch.await();
System.out.println("All threads finished");
}
}
死锁是并发编程中常见的问题,发生在多个线程互相等待对方释放资源时。避免死锁的策略包括按顺序获取锁、使用超时机制和避免嵌套锁。合理设计锁的获取顺序可以显著降低死锁风险。
// 按顺序获取锁
public class DeadlockExample {
private final Object lock1 = new Object();
private final Object lock2 = new Object();
public void method1() {
synchronized (lock1) {
synchronized (lock2) {
// 操作
}
}
}
public void method2() {
synchronized (lock1) {
synchronized (lock2) {
// 操作
}
}
}
}
并发编程的性能优化包括减少锁的粒度、使用读写锁、避免不必要的同步等。ReadWriteLock
允许多个读线程同时访问共享资源,提高读操作的并发性。
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Cache {
private ReadWriteLock lock = new ReentrantReadWriteLock();
private Object data;
public Object getData() {
lock.readLock().lock();
try {
return data;
} finally {
lock.readLock().unlock();
}
}
public void setData(Object data) {
lock.writeLock().lock();
try {
this.data = data;
} finally {
lock.writeLock().unlock();
}
}
}