并发与并行的区别
1. 定义区别
-
并发(Concurrency)
- 表示多个任务在同一时间段内交替执行,但不一定同时运行。
- 核心在于任务的逻辑调度。
- 比喻:一个服务员为多个桌子上的顾客服务,他快速切换去满足不同顾客的需求。
-
并行(Parallelism)
- 表示多个任务在同一时刻同时运行,通常需要多核处理器的支持。
- 核心在于任务的物理同时性。
- 比喻:多个服务员分别为不同的桌子同时服务。
2. 实现方式
-
并发
- 通过操作系统的线程调度机制实现,一个核心通过快速切换任务来模拟同时执行。
- 硬件需求:单核或多核处理器均可。
- 语言支持:例如 Java 的线程池、协程,Python 的 asyncio。
-
并行
- 通过多核或多处理器来实现多个任务同时执行。
- 硬件需求:多核或分布式处理器。
- 技术支持:如 CUDA(GPU并行计算)、MPI(分布式并行计算)。
优化方案
场景:前端一个页面需要同时调用后台三个接口,每个接口时间都不快,导致页面响应时间慢,需要进行优化。
方案:分析每个接口的调用时长,看各个接口内部是否还有优化空间;同时将前端内部串行调用改成并发调用,使用自定义线程池+CompletableFuture
类。
Controller层代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@RestController
public class ConcurrentController {
@Autowired
private ConcurrentService concurrentService;
@GetMapping("/startConcurrentTask")
public String startConcurrentTask() throws ExecutionException, InterruptedException {
//获取当前时间
long startTime = System.currentTimeMillis();
// 调用三个异步服务
CompletableFuture<String> future1 = concurrentService.callService1();
CompletableFuture<String> future2 = concurrentService.callService2();
CompletableFuture<String> future3 = concurrentService.callService3();
// 等待所有异步任务完成并合并结果
CompletableFuture<String> combinedFuture = CompletableFuture.allOf(future1, future2, future3)
.thenApply(v -> {
try {
String result1 = future1.get();
String result2 = future2.get();
String result3 = future3.get();
return combineResults(result1, result2, result3);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
// 获取最终结果
String finalResult = combinedFuture.get();
System.out.println("Final Result: " + finalResult);
// 计算总耗时
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println("Total Time: " + totalTime + " milliseconds");
return finalResult;
}
private String combineResults(String result1, String result2, String result3) {
return result1 + ", " + result2 + ", " + result3;
}
}
Service层代码
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;
@Service
public class ConcurrentService {
@Async("taskExecutor") // 使用自定义线程池
public CompletableFuture<String> callService1() {
try {
Thread.sleep(1000); // 模拟耗时操作
} catch (InterruptedException e) {
e.printStackTrace();
}
return CompletableFuture.completedFuture("Result from Service 1");
}
@Async("taskExecutor")
public CompletableFuture<String> callService2() {
try {
Thread.sleep(1500); // 模拟耗时操作
} catch (InterruptedException e) {
e.printStackTrace();
}
return CompletableFuture.completedFuture("Result from Service 2");
}
@Async("taskExecutor")
public CompletableFuture<String> callService3() {
try {
Thread.sleep(1200); // 模拟耗时操作
} catch (InterruptedException e) {
e.printStackTrace();
}
return CompletableFuture.completedFuture("Result from Service 3");
}
}
配置类:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
@EnableAsync // 启用异步支持
public class AsyncConfig {
@Bean(name = "taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(25);
executor.setThreadNamePrefix("async-task-");
executor.initialize();
return executor;
}
}