线程池的使用

线程池的使用

根据项目需要进行对图片的压缩和上传,但由于压缩和上传相应时间比较长,返回时间不在允许范围内故此需要优化;优化方案最终采用线程池的形式降低系统资源消耗,以下为实现过程

逻辑层调用
1.把任务数据封装到CompressAndUpLoadFileTask;
2.调用 consumerUtil.putTask(task);把封装类放入到队列中去

	String path= picts.getPicPath();//图片原地址
			compresspath = path.substring(0,path.lastIndexOf("."))+"-compress"+path.substring(path.lastIndexOf("."));//压缩后地址
			//使用线程池进行文件的上传和压缩
			//初始化任务数据
			CompressAndUpLoadFileTask task= new CompressAndUpLoadFileTask(path,compresspath, compresspath);
			consumerUtil.putTask(task);

任务的数据封装类

@Data
public class CompressAndUpLoadFileTask {
    private String srcPath;
    private String compressPath;
    private String uploadPath;
    public CompressAndUpLoadFileTask(String srcPath, String compressPath, String uploadPath) {
        this.srcPath = srcPath;
        this.uploadPath = uploadPath;
        this.compressPath = compressPath;
    }
    public CompressAndUpLoadFileTask(String srcPath) {
        this.srcPath = srcPath;
    }
}

接下来查看 consumerUtil类的具体实现
不难发现,consumerUtil先是创建了一个大小为1千的ArrayBlockingQueue的消息队列

@Component
public class ConsumerUtil  implements InitializingBean, BeanPostProcessor {
    private ArrayBlockingQueue<CompressAndUpLoadFileTask> arrayBlockingQueue = new ArrayBlockingQueue(1000);
    private static volatile ConsumerUtil consumerUtil = null;
    private  Thread consumerThread = null;
    private  volatile boolean isStop = false;
    @Value(value = "${aicar.remote.sshname}")
    private String sshname;
    @Value(value = "${aicar.remote.sshpasword}")
    private String sshpasword;
    @Value(value = "${aicar.remote.sshhost}")
    private String sshhost;
    @Value(value = "${aicar.remote.sshport}")
    private Integer sshport;
    private final ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(8); // 创建一个大小为8的固定线程池,可以按照CPU的核数初步判定,如果CPU密集性任务则创建N+1个,如果是IO密集型任务则创建2N+1个,其中N即CPU的核数
    private ConsumerUtil (){
        consumerThread = new Thread(){
            @SneakyThrows
            @Override
            public void run() {
                while (true){
                    CompressAndUpLoadFileTask task = arrayBlockingQueue.poll(3, TimeUnit.SECONDS);
                    if(task==null){
                        continue;
                    }
                    if(isStop){
                        return;
                    }
                    //图片存到服务器对应文件夹下
                    executor.execute(new Runnable() {
                        public void run() {
                            // 打印正在执行的缓存线程信息
                            ReduceImgUtil.reduceImg(task.getSrcPath(),task.getCompressPath());//压缩图片
                            try {
                                new SftpUploadUtil(sshname, sshpasword, sshhost, sshport).uploadFile(task.getUploadPath(),task.getCompressPath());
                            } catch (SftpException e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }
            }
        };
        consumerThread.start();
    }
    public void stop(){
        isStop = true;
    }

    public void putTask(CompressAndUpLoadFileTask upLoadFileTask){
        try {
            this.arrayBlockingQueue.put(upLoadFileTask);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
    }

    @Data
    public static class CompressAndUpLoadFileTask {
        public CompressAndUpLoadFileTask(String srcPath, String compressPath,String uploadPath) {
            this.srcPath = srcPath;
            this.uploadPath = uploadPath;
            this.compressPath = compressPath;
        }

        public CompressAndUpLoadFileTask(String srcPath) {
            this.srcPath = srcPath;
        }
        private String srcPath;
        private String compressPath;
        private String uploadPath;

    }
}

其实类在加载的时候线程已经启动了
逻辑层引入线程池相关类

ConsumerUtil工具类创建了一个大小为8的固定线程池
在这里插入图片描述
这一部分就是我们主要的任务,压缩图片然后进行图片上传操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值