Java并发API是Java语言中用于多线程编程的核心工具包,主要位于java.util.concurrent
和java.util.concurrent.locks
包中。它提供了高效、简洁的方式来处理并发编程中的常见问题。
run()
方法,用于指定线程的执行逻辑。ConcurrentHashMap
、CopyOnWriteArrayList
等,适合多线程环境下的数据存储。AtomicInteger
、AtomicLong
等,用于线程安全地更新单个变量。线程安全是并发编程中的核心问题,主要由于共享资源的访问冲突导致。Java提供了多种机制来解决线程安全问题。
线程安全的原因:
同步机制:
synchronized
关键字:
方法级同步:将方法声明为synchronized
,确保同一时间只有一个线程执行该方法。
块级同步:只对指定的代码块加锁,减少锁的粒度。
示例:
public synchronized void method() {
// 同步方法
}
ReentrantLock
:
提供了更灵活的锁机制,可以手动加锁和解锁。
示例:
ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
// 需要同步的代码
} finally {
lock.unlock();
}
volatile关键字:
线程安全的策略:
String
、Integer
等。Executor框架是Java并发API中用于管理线程池的核心工具,简化了线程的创建和管理。
Executor框架的核心接口:
execute()
方法,用于提交任务。Executor
,增加了shutdown()
、invokeAll()
等方法。ThreadPoolExecutor的工作原理:
execute()
或submit()
提交任务。ThreadPoolExecutor的配置参数:
ThreadPoolExecutor的使用示例:
ExecutorService executor = new ThreadPoolExecutor(
5, // 核心线程数
10, // 最大线程数
60L, // 空闲时间
TimeUnit.SECONDS,
new LinkedBlockingQueue() // 任务队列
);
// 提交任务
executor.execute(new Runnable() {
@Override
public void run() {
System.out.println("Task executed by thread: " + Thread.currentThread().getName());
}
});
// 关闭线程池
executor.shutdown();
常见的线程池配置:
newFixedThreadPool()
方法。newCachedThreadPool()
方法。newSingleThreadExecutor()
方法。Lock
接口是Java并发API中提供的一种更灵活的锁机制,用于手动加锁和解锁。
Lock接口的核心方法:
lock()
: 获取锁。unlock()
: 释放锁。tryLock()
: 尝试获取锁,如果锁被其他线程持有,则返回false
。tryLock(long time, TimeUnit unit)
: 在指定时间内尝试获取锁。Condition接口:
Condition
是Lock
接口的补充,用于实现线程间的通信。await()
: 使当前线程等待,直到被其他线程唤醒。signal()
: 唤醒一个等待的线程。signalAll()
: 唤醒所有等待的线程。Lock与synchronized的对比:
使用示例:
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
// 线程A
lock.lock();
try {
System.out.println("Thread A: 开始等待");
condition.await();
System.out.println("Thread A: 被唤醒");
} finally {
lock.unlock();
}
// 线程B
lock.lock();
try {
Thread.sleep(1000);
System.out.println("Thread B: 唤醒线程A");
condition.signal();
} finally {
lock.unlock();
}
并发集合是专门为多线程环境设计的集合类,提供线程安全的数据存取操作。
常见的并发集合:
HashMap
,支持高效的读写操作。ArrayList
,通过复制数组实现线程安全。put()
和take()
)。ConcurrentHashMap的实现原理:
CopyOnWriteArrayList的实现原理:
add()
、remove()
)都会创建一个新的数组副本,确保读操作的安全性。使用示例:
// 使用ConcurrentHashMap
ConcurrentHashMap map = new ConcurrentHashMap<>();
map.put("key1", "value1");
System.out.println(map.get("key1"));
// 使用CopyOnWriteArrayList
CopyOnWriteArrayList list = new CopyOnWriteArrayList<>();
list.add("element1");
for (String element : list) {
System.out.println(element);
}
原子变量(Atomic Variables)是Java并发API中提供的一组线程安全的单个变量类,用于在多线程环境中安全地更新单个变量。
常见的原子变量类:
原子变量的工作原理:
使用示例:
AtomicInteger atomicInt = new AtomicInteger(0);
// 安全地增加1
int oldValue = atomicInt.get();
int newValue = atomicInt.compareAndSet(oldValue, oldValue + 1) ? oldValue + 1 : oldValue;
System.out.println("New value: " + newValue);
原子变量的优势:
synchronized
和Lock
更高效。编写高效、可靠的多线程程序需要遵循一些最佳实践。
String
、Integer
)在多线程环境中是线程安全的。synchronized
或Lock
保护共享资源。ThreadPoolExecutor
)管理线程,避免频繁创建和销毁线程。Thread.interrupted()
检查线程是否被中断。Thread.stop()
已被废弃,使用interrupt()
方法中断线程。shutdown()
方法关闭线程池,避免直接调用System.exit()
。以下是一个综合案例,展示了Java并发与多线程的多个知识点在实际场景中的应用。这是一个模拟电商平台的秒杀系统,旨在解决高并发场景下的线程安全、任务队列管理、并发控制等问题。
电商平台上一个秒杀活动需要处理大量用户的并发请求。要求在有限时间内(如1秒)处理成千上万的请求,同时确保库存安全、数据一致性和系统稳定性。
ThreadPoolExecutor
创建固定大小的线程池,处理秒杀请求。ReentrantLock
和Condition
控制秒杀的开始和结束。ConcurrentHashMap
记录用户秒杀请求和库存。LinkedBlockingQueue
管理秒杀请求。AtomicInteger
记录秒杀剩余数量。import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
public class SecKillSystem {
private static final Logger LOGGER = Logger.getLogger(SecKillSystem.class.getName());
// 秒杀执行器
private final ExecutorService executor;
// 用于控制秒杀的开始和结束
private final java.util.concurrent.locks.ReentrantLock lock = new java.util.concurrent.locks.ReentrantLock();
private final java.util.concurrent.locks.Condition condition = lock.newCondition();
// 秒杀商品池
private final CopyOnWriteArrayList goodsPool = new CopyOnWriteArrayList<>();
// 用户秒杀请求队列
private final BlockingQueue requestQueue = new LinkedBlockingQueue<>();
// 用户秒杀结果记录
private final ConcurrentHashMap resultMap = new ConcurrentHashMap<>();
// 剩余库存(原子变量)
private final AtomicInteger remainingStock = new AtomicInteger(0);
public SecKillSystem(int threadPoolSize) {
this.executor = Executors.newFixedThreadPool(threadPoolSize);
}
// 初始化秒杀商品
public void initSecKill(Goods goods) {
goodsPool.add(goods);
remainingStock.set(goods.getStock());
LOGGER.info("Initialized secKill goods: " + goods.getName() + ", stock: " + goods.getStock());
}
// 开始秒杀
public void startSecKill() {
lock.lock();
try {
LOGGER.info("Starting secKill...");
condition.signalAll(); // 唤醒所有等待的线程
} finally {
lock.unlock();
}
}
// 提交秒杀请求
public void submitRequest(User user, Goods goods) {
try {
requestQueue.put(new UserRequest(user, goods));
LOGGER.info("User " + user.getId() + " submitted request for " + goods.getName());
} catch (InterruptedException e) {
LOGGER.warning("Interrupted while submitting request: " + e.getMessage());
Thread.currentThread().interrupt();
}
}
// 处理秒杀请求
private void processRequests() {
executor.execute(() -> {
while (true) {
try {
UserRequest request = requestQueue.take(); // 阻塞获取请求
if (isSecKillActive()) {
handleRequest(request);
} else {
LOGGER.info("SecKill is not active, rejecting request");
resultMap.put(request.getUser().getId(), false);
}
} catch (InterruptedException e) {
LOGGER.warning("Interrupted while processing requests: " + e.getMessage());
Thread.currentThread().interrupt();
}
}
});
}
// 检查秒杀是否活跃
private boolean isSecKillActive() {
lock.lock();
try {
return remainingStock.get() > 0;
} finally {
lock.unlock();
}
}
// 处理单个秒杀请求
private void handleRequest(UserRequest request) {
Goods goods = request.getGoods();
if (goods.getStock() <= 0) {
LOGGER.info("Goods " + goods.getName() + " is sold out");
resultMap.put(request.getUser().getId(), false);
return;
}
try {
boolean success = goods.decreaseStock();
if (success) {
LOGGER.info("User " + request.getUser().getId() + " successfully got " + goods.getName());
resultMap.put(request.getUser().getId(), true);
} else {
LOGGER.info("Failed to process request for user " + request.getUser().getId());
resultMap.put(request.getUser().getId(), false);
}
} catch (Exception e) {
LOGGER.severe("Error processing request: " + e.getMessage());
resultMap.put(request.getUser().getId(), false);
}
}
// 关闭秒杀系统
public void shutDown() {
executor.shutdown();
try {
if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
LOGGER.warning("Executor did not terminate");
}
} catch (InterruptedException e) {
LOGGER.warning("Interrupted while shutting down: " + e.getMessage());
Thread.currentThread().interrupt();
}
}
public static class Goods {
private final String name;
private final AtomicInteger stock;
public Goods(String name, int stock) {
this.name = name;
this.stock = new AtomicInteger(stock);
}
public String getName() {
return name;
}
public AtomicInteger getStock() {
return stock;
}
public boolean decreaseStock() {
int currentStock = stock.get();
if (currentStock <= 0) {
return false;
}
return stock.compareAndSet(currentStock, currentStock - 1);
}
}
public static class User {
private final String id;
public User(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
public static class UserRequest {
private final User user;
private final Goods goods;
public UserRequest(User user, Goods goods) {
this.user = user;
this.goods = goods;
}
public User getUser() {
return user;
}
public Goods getGoods() {
return goods;
}
}
public static void main(String[] args) {
// 初始化秒杀系统
SecKillSystem secKillSystem = new SecKillSystem(10); // 创建10个线程的线程池
// 创建商品
Goods iPhone = new Goods("iPhone 15", 100);
Goods macBook = new Goods("MacBook Pro", 50);
// 初始化商品到秒杀系统
secKillSystem.initSecKill(iPhone);
secKillSystem.initSecKill(macBook);
// 模拟用户提交请求
for (int i = 1; i <= 200; i++) {
User user = new User("user_" + i);
Goods goods = (i % 2 == 0) ? macBook : iPhone;
secKillSystem.submitRequest(user, goods);
}
// 开始秒杀
secKillSystem.startSecKill();
// 关闭秒杀系统
try {
Thread.sleep(5000); // 等待5秒
secKillSystem.shutDown();
} catch (InterruptedException e) {
LOGGER.warning("Interrupted while waiting for secKill to complete: " + e.getMessage());
Thread.currentThread().interrupt();
}
// 输出结果
LOGGER.info("SecKill results: " + secKillSystem.resultMap);
}
}
ThreadPoolExecutor
创建固定大小的线程池,处理秒杀请求。Condition
实现线程间通信,唤醒等待的线程。LinkedBlockingQueue
管理秒杀请求,实现线程安全的队列操作。ConcurrentHashMap
记录秒杀结果,确保线程安全。CopyOnWriteArrayList
管理秒杀商品,适合读多写少的场景。volatile
关键字:确保线程间的可见性和有序性。try-catch
块中处理中断异常,避免无限循环。