异步多线程

提前了解

  1. 一个HTTP请求会对应一个独立的线程,Servlet容器自动管理这些线程
  2. 数据库连接池是管理连接对象的(强调数据库资源),会被数据库管理系统自动管理;线程池是管理线程对象的(强调操作系统资源)
  3. 事务强调的是一组操作,不仅仅只用在数据库中,例如@Transaction

 

什么是异步多线程

说的很顺口,讲起来却傻傻分不清。

  • 异步:执行某耗时操作时(文件上传、数据处理、外部服务调用)不用阻塞主线程,而是可以继续执行其他操作。
  • 多线程:并行处理不同任务的一种方式
  • 两者的关系:异步的实现不一定依赖多线程,但多线程是实现异步的一种方式

故当我们说起异步多线程时,表达的真正含义是使用多线程实现异步操作。

 

为什么要进行异步操作

  1. 耗时少:减少阻塞时间,提高响应速度,从而提升吞吐量,提升用户体验
  2. 高并发环境:不用阻塞,减少线程数量,提高系统性能

 

什么情况下该使用异步操作

  1. 文件上传下载、数据处理、外部服务调用
  2. 待补充

 

多线程编程

线程池管理

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.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
 
@Configuration
@EnableAsync // 开启异步方法
public class ThreadPoolConfig {
 
    @Bean
    public ExecutorService executorService() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        // 设置核心线程数
        threadPoolTaskExecutor.setCorePoolSize(16);
        // 设置最大线程数
        threadPoolTaskExecutor.setMaxPoolSize(16);
        // 设置任务队列大小
        threadPoolTaskExecutor.setQueueCapacity(2000);
        // 设置线程名称前缀
        threadPoolTaskExecutor.setThreadNamePrefix("threadPoolTaskExecutor-->");
        // 设置拒绝策略.当工作队列已满,线程数为最大线程数的时候,接收新任务交给主线程执行
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 初始化线程池
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor.getThreadPoolExecutor();
    }
}
@Service
public class AsyncServiceImpl implements AsyncService {

    @Override
    @Async("asyncServiceExecutor") // value参数:指定线程池
    public void executeAsync() {
    
        System.out.println("异步线程要做的事情");
        
    }
}

 

异步处理获取结果

@RestController
public class MyController {

    @Autowired
    private MyService myService;

    @GetMapping("/test-async")
    public String testAsync() throws InterruptedException, ExecutionException {
        // 调用异步方法
        CompletableFuture<String> future = myService.asyncMethod();
        
        // 等待异步任务完成并获取结果
        String result = future.get();  // 阻塞等待结果
        return result;
    }
}

 

线程安全

public class Ticket implements Runnable {

    private final Lock lock = new ReentrantLock();
    private int tickets = 100;

    @Override
    public void run() {
        while (true) {
            // 加锁
            this.lock.lock();
            try {
                if (this.tickets > 0) {
                    System.out.println(Thread.currentThread().getName() + "卖第" + this.tickets-- + "张票");
                }
            } finally {
                // 释放锁
                this.lock.unlock();
            }
        }
    }
}

 

posted @   先娶国王后取经  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
历史上的今天:
2024-01-03 redis容器docker-compose启动正常,但配置文件无法生效
2024-01-03 Redis过期回调机制
2023-01-03 Navicat破解
2023-01-03 将一台服务器上的数据库迁移到另一台服务器上
点击右上角即可分享
微信分享提示