Java多线程编程是实现并发程序的重要技术,能够有效提升程序性能和资源利用率。以下是Java多线程的核心知识点及实践指南:
创建线程的三种方式
继承Thread类:
java
class MyThread extends Thread {
public void run() {
System.out.println("Thread running");
}
}
new MyThread().start();实现Runnable接口(推荐,避免单继承局限):
java
class MyTask implements Runnable {
public void run() {
System.out.println("Task running");
}
}
new Thread(new MyTask()).start();实现Callable接口(支持返回值):
java
class MyCallable implements Callable<String> {
public String call() throws Exception {
return "Callable result";
}
}
FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
new Thread(futureTask).start();
System.out.println(futureTask.get()); // 获取返回值线程池(ThreadPoolExecutor)
手动创建线程池(推荐方式):
java
int corePoolSize = 5;
int maxPoolSize = 10;
long keepAliveTime = 1L;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(100);
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue
);
executor.execute(() -> System.out.println("Task executed"));常用线程池类型:
FixedThreadPool:固定线程数,适合负载较重的服务器。
CachedThreadPool:线程数按需创建,适合短期异步任务。
SingleThreadExecutor:单个线程顺序执行任务。
synchronized关键字
同步方法:
java
public synchronized void syncMethod() {
// 同步代码
}同步代码块:
java
public void method() {
synchronized(this) {
// 同步代码
}
}ReentrantLock(可重入锁)
java
private final Lock lock = new ReentrantLock();
public void performTask() {
lock.lock();
try {
// 临界区代码
} finally {
lock.unlock();
}
}ReadWriteLock(读写锁)
java
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
public void readData() {
rwLock.readLock().lock();
try {
// 读操作
} finally {
rwLock.readLock().unlock();
}
}
public void writeData() {
rwLock.writeLock().lock();
try {
// 写操作
} finally {
rwLock.writeLock().unlock();
}
}原子类(Atomic Classes)
java
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet(); // 原子操作
}wait()/notify()机制
java
synchronized(lock) {
while (conditionNotMet) {
lock.wait(); // 释放锁并等待
}
// 执行任务
lock.notifyAll(); // 唤醒所有等待线程
}Condition接口(配合Lock使用)
java
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void awaitMethod() throws InterruptedException {
lock.lock();
try {
condition.await(); // 类似wait()
} finally {
lock.unlock();
}
}
public void signalMethod() {
lock.lock();
try {
condition.signal(); // 类似notify()
} finally {
lock.unlock();
}
}CountDownLatch(倒计时门闩)
java
CountDownLatch latch = new CountDownLatch(3);
// 线程完成任务后调用latch.countDown()
latch.await(); // 主线程等待所有任务完成CyclicBarrier(循环屏障)
java
CyclicBarrier barrier = new CyclicBarrier(3, () ->
System.out.println("All threads reached barrier"));
// 线程调用barrier.await()等待其他线程Semaphore(信号量)
java
Semaphore semaphore = new Semaphore(5); // 允许5个线程同时访问
semaphore.acquire(); // 获取许可
try {
// 访问资源
} finally {
semaphore.release(); // 释放许可
}Exchanger(交换器)
java
Exchanger<String> exchanger = new Exchanger<>();
// 线程A
String dataA = exchanger.exchange("Data from A");
// 线程B
String dataB = exchanger.exchange("Data from B");CompletableFuture(异步编程)
java
CompletableFuture.supplyAsync(() -> "Hello")
.thenApplyAsync(s -> s + " World")
.thenAccept(System.out::println);Fork/Join框架(分治任务)
java
class MyTask extends RecursiveTask<Integer> {
protected Integer compute() {
// 分解任务并合并结果
}
}
ForkJoinPool pool = new ForkJoinPool();
pool.invoke(new MyTask());ThreadLocal(线程局部变量)
java
private static ThreadLocal<SimpleDateFormat> dateFormat =
ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));死锁预防:按固定顺序获取锁,使用尝试锁(tryLock())。
资源竞争:最小化同步代码块,使用并发集合(如ConcurrentHashMap)。
内存可见性:使用volatile变量或原子类确保修改可见性。
线程泄漏:确保线程池正确关闭,任务处理异常。
合理设置线程池大小:
CPU密集型:线程数 = CPU核心数 + 1
IO密集型:线程数 = CPU核心数 * (1 + 平均等待时间/计算时间)
减少锁竞争:使用分段锁、无锁数据结构(如Disruptor框架)。
监控工具:使用JConsole、VisualVM分析线程状态,检测死锁。
示例:生产者-消费者模型
java
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);
// 生产者
new Thread(() -> {
while (true) {
int num = produceItem();
queue.put(num); // 阻塞直到队列有空位
}
}).start();
// 消费者
new Thread(() -> {
while (true) {
int num = queue.take(); // 阻塞直到队列有元素
consumeItem(num);
}
}).start();掌握这些核心概念和工具,能够有效开发高效、健壮的Java多线程应用。实际开发中需结合具体场景选择合适的并发策略,并通过测试确保线程安全与性能达标。