在Java中,多线程编程是一个重要的主题,特别是在性能和响应速度要求较高的应用中。在Java中,Java并发包(Java Util Concurrent,简称JUC)提供了一些强大的工具来支持多线程编程。以下是一些高频考点和JUC常见类的详细总结,建议收藏。
1. ExecutorService
ExecutorService
是一个用于管理线程的高级接口,它简化了线程的创建和管理。我们可以通过它来执行并发任务,而不需要手动创建和管理Thread对象。
示例代码:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorServiceExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 1; i <= 5; i++) {
final int taskId = i;
executor.execute(() -> {
System.out.println("任务 " + taskId + " 正在执行, 线程: " + Thread.currentThread().getName());
});
}
executor.shutdown();
}
}
2. Future
Future
是执行异步任务的结果表示。通过Future
可以获取任务的执行状态和结果。
示例代码:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class FutureExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(new Callable<Integer>() {
@Override
public Integer call() {
// 模拟耗时任务
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 42;
}
});
// 任务完成后,可以获取结果
System.out.println("任务执行结果: " + future.get());
executor.shutdown();
}
}
3. CountDownLatch
CountDownLatch
是一个同步辅助类,允许一个或多个线程等待直到在其他线程中执行的一组操作完成。它非常适合用于协调多个线程的启动。
示例代码:
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
int numberOfThreads = 3;
CountDownLatch latch = new CountDownLatch(numberOfThreads);
for (int i = 0; i < numberOfThreads; i++) {
new Thread(() -> {
try {
Thread.sleep(1000); // 模拟任务工作
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 完成工作");
latch.countDown();
}).start();
}
latch.await(); // 等待所有线程完成
System.out.println("所有线程完成,主线程继续执行");
}
}
4. CyclicBarrier
CyclicBarrier
允许一组线程互相等待,直到所有线程都达到某个公共屏障点。之后,线程能够继续执行,并且可以重复使用。
示例代码:
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
int numberOfThreads = 3;
CyclicBarrier barrier = new CyclicBarrier(numberOfThreads, () -> {
System.out.println("所有线程已到达屏障,继续执行...");
});
for (int i = 0; i < numberOfThreads; i++) {
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + " 正在准备");
Thread.sleep(1000); // 模拟准备工作
barrier.await(); // 等待其他线程到达
System.out.println(Thread.currentThread().getName() + " 继续执行");
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}
5. Semaphore
Semaphore
是一个计数信号量,用于控制对某个资源的访问数量。适用于资源池的管理,如数据库连接池。
示例代码:
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) {
final Semaphore semaphore = new Semaphore(2); // 允许两个线程同时访问资源
for (int i = 0; i < 5; i++) {
final int threadId = i;
new Thread(() -> {
try {
semaphore.acquire(); // 获取许可
System.out.println("线程 " + threadId + " 已获得许可,执行工作中...");
Thread.sleep(2000); // 模拟工作
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("线程 " + threadId + " 释放许可");
semaphore.release(); // 释放许可
}
}).start();
}
}
}
总结
Java的并发编程虽然复杂,但JUC提供了许多优雅且易用的类来帮助我们简化实现。在面试中,理解这些类的功能及其适用场景,对于解答多线程相关的问题至关重要。希望以上总结对你有所帮助,建议收藏以备后用!