Rumah >Java >javaTutorial >Kaedah dipanggil asynchronously oleh @Async dalam java
Panggilan tak segerak dan panggilan segerak
Panggilan segerak: pelaksanaan berurutan, kembalikan hasilnya dengan panggilan Laksanakan panggilan seterusnya
Panggilan tak segerak: Dengan membuat panggilan, tidak perlu menunggu hasil pemulangan, laksanakan panggilan seterusnya
Kod anotasi @Async adalah seperti berikut:
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Async { String value() default ""; }
Anotasi boleh digunakan dalam jenis dan kaedah
Tentukan nilainya melalui nilai, lalainya kosong
Secara amnya, anotasi ini perlu dipadankan @EnableAsync, kod asal adalah seperti berikut
@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; }
Terutamanya letakkan anotasi ini dalam kelas permulaan untuk permulaan konfigurasi
Tambah yang berikut dalam kelas permulaan:
@SpringbootApplication @EnableAsync public class Application{ public static void main(String[] args){ SrpingApplication.run(Application.class, args); } }
Langkah seterusnya hanya boleh dilaksanakan daripada panggilan ke hasil fungsi yang dikembalikan, yang dipanggil segerak panggil
Kod lapisan perkhidmatan:
public class Service{ public void test01() throws InterruptedException{ Thread.sleep(5000); System.out.println("保存日志"); } }
Modul kod lapisan kawalan:
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(); } } }
Selepas bermula melalui kelas permulaan springboot
Keluaran adalah seperti berikut:
Mula
// Ini untuk menunggu selama 5 saat, terminal tidak Paparan tidak ditutup
Tamat
Panggilan tak segerak, fungsi pelaksana boleh melaksanakan langkah seterusnya tanpa menunggu hasil pemulangan
kod Lapisan perkhidmatan:
Terutamanya menambah anotasi @Async untuk mengenal pasti kaedah ini
public class Service{ @Async public void test01() throws InterruptedException{ Thread.sleep(500); System.out.println("保存日志"); } }
Modul kod lapisan kawalan:
Dengan memanggil fungsi lapisan perkhidmatan
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(); } } }
dan dalam kelas permulaan Tambah anotasi untuk memulakan @EnableAsync
@SpringbootApplication @EnableAsync public class Application{ public static void main(String[] args){ SrpingApplication.run(Application.class, args); } }
Untuk pengetahuan asas tentang kumpulan benang, sila lihat artikel saya sebelum ini:
Cara menutup benang dalam Java Dan kumpulan benang dengan betul (amalan kod termasuk analisis kod sumber)
Analisis terperinci tentang cara membuat kumpulan benang java (penuh)
Jika anda tidak menentukan kumpulan benang, kumpulan benang lalai yang digunakan ialah SimpleAsyncTaskExecutor (buat satu apabila tugas datang) Benang, penciptaan benang yang berterusan kepada CPU dan OOM yang berlebihan). Kumpulan benang terbina dalam secara amnya mempunyai kelemahan Umumnya disyorkan untuk menggunakan ThreadPoolExecutor (kosongkan sumber kumpulan benang untuk mengelakkan risiko)
Butirannya adalah seperti berikut:
newFixedThreadPool: Bilangan utas ditetapkan, tetapi baris gilir tugasan masih tidak terhad (bilangan maksimum utas hanya akan dibuat apabila baris gilir penuh), jadi ia akan menyebabkan OOM
newCachedThreadPool: Tiada had atas untuk bilangan maksimum utas adalah terdedah kepada ketinggalan atau mengarahkan OOM
Anda. boleh melaraskan konfigurasi kumpulan benang melalui kumpulan benang tersuai, yang lebih baik Penggunaan sumber
Anotasi @Async mencari antara muka AsyncConfigurer (kelas pelaksanaan ialah AsyncConfigurerSupport, konfigurasi lalai dan kaedah kosong), jadi antara muka boleh ditulis semula untuk menentukan kumpulan benang.
Mewarisi AsyncConfigurerSupport
dengan melaksanakan antara muka AsyncConfigurer
Peranti)
Kaedah ketiga:
Tentukan beberapa pembolehubah kumpulan benang dalam aplikasi.xml
thread.core.size=16 thread.max.size=16 thread.queue.size=30 thread.prefix=xx-
Sesuaikan kumpulan benang seperti berikut
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; } }
Atas ialah kandungan terperinci Kaedah dipanggil asynchronously oleh @Async dalam java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!