91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java中@Async異步調用的方法

發布時間:2022-07-14 10:21:25 來源:億速云 閱讀:482 作者:iii 欄目:開發技術

本篇內容主要講解“java中@Async異步調用的方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“java中@Async異步調用的方法”吧!

    前言

    異步調用與同步調用

    • 同步調用:順序執行,通過調用返回結果再次執行下一個調用

    • 異步調用:通過調用,無需等待返回結果,執行下一個調用

    1. @Async講解

    其@Async的注解代碼如下:

    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Async {
        String value() default "";
    }

    注解可以使用在類型以及方法中
    通過value定義其值,默認是空

    一般這個注解需要配合@EnableAsync,起源碼如下

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import({AsyncConfigurationSelector.class})
    public @interface EnableAsync {
        Class<? extends Annotation> annotation() default Annotation.class;
    
        boolean proxyTargetClass() default false;
    
        AdviceMode mode() default AdviceMode.PROXY;
    
        int order() default Integer.MAX_VALUE;
    }

    主要通過該注解放置在啟動類中進行配置啟動

    在啟動類中添加如下:

    @SpringbootApplication
    @EnableAsync
    public class Application{
        public static void main(String[] args){
            SrpingApplication.run(Application.class, args);
        }
    }

    2. 用法

    2.1 同步調用

    從調用到返回函數結果才能執行下一步,稱為同步調用

    service層 代碼:

    public class Service{
        public void test01() throws InterruptedException{
            Thread.sleep(5000);
            System.out.println("保存日志");
        }
    }

    控制層代碼模塊:

    public class Controler{
        @Autowired
        private Service service;
    
        @GetMapping("/test")
        public String getTest(){
            try{
                System.out.println("開始");
                service.test01();
                System.out.println("結束");            
            }catch(InterruptedException e){
                e.prinStackTrace();
            }
        }
        
    }

    通過springboot的啟動類啟動之后

    輸出如下:

    開始

    // 此為等待5秒鐘,終端不顯示也不關閉

    結束

    2.2 異步調用

    異步調用,執行函數不用等返回結果就可以執行下一步

    service層 代碼:
    主要是添加了@Async注解標識這個方法

    public class Service{
        @Async
        public void test01() throws InterruptedException{
            Thread.sleep(500);
            System.out.println("保存日志");
        }
    }

    控制層代碼模塊:

    通過調用service層函數

    public class Controler{
        @Autowired
        private Service service;
    
        @GetMapping("/test")
        public String getTest(){
            try{
                System.out.println("開始");
                service.test01();
                System.out.println("結束");            
            }catch(InterruptedException e){
                e.prinStackTrace();
            }
        }
        
    }

    以及在啟動類中加入注解啟動 @EnableAsync

    @SpringbootApplication
    @EnableAsync
    public class Application{
        public static void main(String[] args){
            SrpingApplication.run(Application.class, args);
        }
    }

    3. 自定義線程池

    對于線程池的一些基本知識可看我之前的文章:

    java如何正確關閉線程以及線程池(代碼實踐含源碼分析)
    java線程池的創建方式詳細分析(全)

    如果不指定線程池,默認使用的線程池為SimpleAsyncTaskExecutor(來一個任務就創建一個線程,不斷創建線程導致CPU過高引發OOM),自帶的線程池一般都有弊端,一般推薦使用ThreadPoolExecutor(明確線程池的資源,規避風險)

    具體如下:

    • newFixedThreadPool:定死了線程數,任務隊列還是無界的,(最大線程數只有隊列滿了,最大線程數才會創建),所以會造成OOM

    • newCachedThreadPool:沒有設置最大線程數上限,創建大量的線程容易卡頓或者直接OOM

    通過自定義線程池可以調整線程池的配置,更好的資源利用

    @Async這個注解查找 AsyncConfigurer接口(實現類為AsyncConfigurerSupport,默認配置和方法都是空),所以可重寫接口指定線程池。

    • 通過實現接口AsyncConfigurer

    • 繼承AsyncConfigurerSupport

    • 自定義TaskExecutor(替代內置任務執行器)

    第三種方法:

    在application.xml中定義線程池的一些變量

    thread.core.size=16
    thread.max.size=16
    thread.queue.size=30
    
    thread.prefix=xx-

    自定義線程池如下

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
    
    import java.util.concurrent.ThreadPoolExecutor;
    
    @Configuration
    public class ThreadPoolConfig {
        // 線程名稱前綴
        @Value("${thread.prefix}")
        private String threadPrefix;
        
        // 核心線程數
        @Value("${thread.core.size}")
        private int coreSize;
    
        // 最大線程數
        @Value("${thread.max.size}")
        private int maxSize;
        
        // 隊列長度
        @Value("${thread.queue.size}")
        private int queueSize;
        
        // 通過bean注解注入
        @Bean("xx")
        public ThreadPoolTaskExecutor taskExecutor() {
            ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
            //設置線程池參數信息
            taskExecutor.setCorePoolSize(coreSize);
            taskExecutor.setMaxPoolSize(maxSize);
            taskExecutor.setQueueCapacity(queueSize);
            taskExecutor.setThreadNamePrefix(threadPrefix);
            taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
            taskExecutor.setAwaitTerminationSeconds(30);
            
            //修改拒絕策略為使用當前線程執行
            taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            
            //初始化線程池
            taskExecutor.initialize();
            return taskExecutor;
        }
    }

    到此,相信大家對“java中@Async異步調用的方法”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    安义县| 谷城县| 岑巩县| 壶关县| 龙海市| 安图县| 怀仁县| 旺苍县| 平武县| 望都县| 永平县| 德惠市| 聂拉木县| 五河县| 西贡区| 达拉特旗| 邛崃市| 银川市| 清苑县| 定远县| 齐河县| 灵山县| 三台县| 聂荣县| 普格县| 灌阳县| 洪湖市| 松溪县| 溧阳市| 大同县| 三原县| 乐平市| 武威市| 永春县| 柯坪县| 华蓥市| 乌苏市| 抚松县| 巫溪县| 张家口市| 灵宝市|