Kaedah Tak Segerak dengan @Async
Pelajari cara melaksanakan kaedah secara tak segerak menggunakan anotasi `@Async` Spring dan kumpulan utas.
Kaedah Tak Segerak dengan @Async ialah pelajaran Panduan Lengkap Spring Boot 4 percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Panduan Lengkap Spring Boot 4, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Panduan Lengkap Spring Boot 4 merangkumi sejumlah 4 pelajaran.
Pengenalan kepada Operasi Tak Segerak
Bayangkan anda memesan makanan dalam talian. Jika aplikasi memaksa anda menunggu tukang masak menyediakan makanan sebelum anda boleh melihat pilihan lain, pengalaman itu tentu kurang baik!
Inilah yang berlaku dalam operasi segerak: satu tugas mesti selesai sebelum tugas seterusnya boleh bermula. Operasi ini menyekat aliran utama.
Namun, operasi tak segerak membolehkan anda memulakan satu tugas dan terus beralih kepada perkara lain. Tugas itu berjalan di latar belakang dan anda akan dimaklumkan apabila tugas tersebut selesai.
- Tidak menyekat: Aplikasi anda kekal responsif.
- Cekap: Penggunaan sumber yang lebih baik dengan melaksanakan beberapa tugas secara serentak.
Demonstrasi Segerak berbanding Tak Segerak
Mari kita lihat contoh Java mudah bagi operasi yang menyekat (segerak). Perhatikan bahawa utas utama menunggu doSyncTask() selesai.
Cuba jalankan contoh ini:
public class Main {
public static void main(String[] args) {
System.out.println("Main thread: Starting sync task...");
long startTime = System.currentTimeMillis();
doSyncTask(); // This call blocks the main thread
long endTime = System.currentTimeMillis();
System.out.println("Main thread: Sync task finished in " + (endTime - startTime) + "ms.");
System.out.println("Main thread: Continues immediately after sync task.");
}
public static void doSyncTask() {
try {
System.out.println("Sync task: Simulating work for 2 seconds...");
Thread.sleep(2000); // Simulate a long operation
System.out.println("Sync task: Completed!");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("Sync task: Interrupted!");
}
}
}Kenali @Async Spring
Spring Boot memudahkan anda menukar kaedah segerak kepada kaedah tak segerak menggunakan anotasi @Async.
Apabila anda menganotasi kaedah dengan @Async:
- Spring melaksanakan kaedah itu dalam utas berasingan.
- Kaedah pemanggil kembali serta-merta tanpa menunggu kaedah
@Asyncselesai. - Anda tidak perlu mengurus utas secara manual!
Aktifkan @Async
Sebelum boleh menggunakan @Async, anda perlu mengaktifkan pemprosesan tak segerak dalam aplikasi Spring Boot anda. Hal ini dilakukan dengan menambahkan anotasi @EnableAsync.
Biasanya, anda meletakkan @EnableAsync pada kelas aplikasi utama atau kelas konfigurasi khusus.
Berikut ialah cara menambahkannya:
package com.coddykit.async;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync // This annotation activates @Async capability
public class AsyncApplication {
public static void main(String[] args) {
SpringApplication.run(AsyncApplication.class, args);
System.out.println("Spring Boot application started with @EnableAsync!");
}
}Asas Kaedah @Async
Setelah @EnableAsync tersedia, anda hanya perlu menambahkan @Async pada mana-mana kaedah awam dalam komponen yang diurus Spring (seperti @Service atau @Component).
Apabila performAsyncTask() dipanggil, utas utama akan mencetak baris seterusnya serta-merta, manakala tugas tak segerak berjalan di latar belakang.
package com.coddykit.async;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class AsyncApplication {
public static void main(String[] args) {
SpringApplication.run(AsyncApplication.class, args);
}
@Bean
public CommandLineRunner run(MyAsyncTaskService service) {
return args -> {
System.out.println("Main thread: Calling async task...");
service.performAsyncTask(); // This call returns immediately
System.out.println("Main thread: Async task called, continuing immediately.");
// Give the async task a chance to finish before the app exits
Thread.sleep(3000);
};
}
}
@Service
class MyAsyncTaskService {
@Async // Mark this method to run asynchronously
public void performAsyncTask() {
try {
System.out.println("Async thread: Starting long task...");
Thread.sleep(2000); // Simulate a long operation
System.out.println("Async thread: Long task completed!");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("Async thread: Task interrupted.");
}
}
}Cara @Async Berfungsi
Apabila anda menggunakan @Async, Spring tidak mencipta utas baharu bagi setiap panggilan. Sebaliknya, Spring menggunakan kumpulan utas.
- Kumpulan utas ialah himpunan utas yang telah dimulakan terlebih dahulu dan boleh melaksanakan tugas.
- Apabila kaedah
@Asyncdipanggil, Spring mengambil utas yang tersedia daripada kumpulan untuk melaksanakannya. - Hal ini mengelakkan kos tambahan kerana perlu mencipta utas baharu secara berterusan dan mengurus sumber sistem dengan cekap.
- Secara lalai, Spring menggunakan
SimpleAsyncTaskExecutor, yang boleh menjadi tidak cekap untuk beban berat.
Dapatkan Hasil dengan Future
Bagaimana jika kaedah tak segerak anda perlu mengembalikan hasil kepada pemanggil? Anda tidak boleh hanya mengembalikan void atau nilai secara langsung.
Untuk tujuan ini, anda menggunakan java.util.concurrent.Future. Objek Future bertindak sebagai ruang letak bagi hasil yang belum tersedia.
- Kaedah
@AsyncmengembalikanFuture<T>(contohnya,Future<String>). - Kod pemanggil boleh memanggil
future.get()kemudian untuk mendapatkan hasil (panggilan ini menyekat sehingga hasil tersedia). - Anda juga boleh menyemak
future.isDone()untuk melihat sama ada tugas telah selesai tanpa menyekat.
package com.coddykit.async;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
import java.util.concurrent.Future;
import java.util.concurrent.AsyncResult;
@SpringBootApplication
@EnableAsync
public class AsyncApplication {
public static void main(String[] args) {
SpringApplication.run(AsyncApplication.class, args);
}
@Bean
public CommandLineRunner run(MyFutureTaskService service) {
return args -> {
System.out.println("Main thread: Calling async task with Future...");
Future<String> futureResult = service.performFutureTask();
System.out.println("Main thread: Async task called, continuing immediately.");
// Main thread can do other work while async task runs
System.out.println("Main thread: Doing other work...");
Thread.sleep(500);
// Wait for the result (this loop checks, future.get() blocks)
while(!futureResult.isDone()) {
System.out.println("Main thread: Waiting for async result...");
Thread.sleep(500);
}
String result = futureResult.get(); // Retrieves the result (blocks if not done)
System.out.println("Main thread: Received result: " + result);
};
}
}
@Service
class MyFutureTaskService {
@Async
public Future<String> performFutureTask() {
try {
System.out.println("Async thread: Starting Future task...");
Thread.sleep(2000); // Simulate a long operation
System.out.println("Async thread: Future task completed!");
return new AsyncResult<>("Task finished successfully!");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return new AsyncResult<>("Task interrupted!");
}
}
}Pengendalian Ralat Tak Segerak
Apabila kaedah @Async (terutamanya kaedah void) melontarkan pengecualian, pengecualian itu tidak disebarkan kembali kepada utas pemanggil secara lalai. Ini bermakna pengecualian tersebut mungkin ditelan secara senyap, lalu menyukarkan penyahpepijatan.
Untuk mengendalikan pengecualian dalam kaedah @Async dengan betul, anda boleh melaksanakan AsyncConfigurer dan menyediakan AsyncUncaughtExceptionHandler tersuai.
- Pengendali ini menangkap sebarang pengecualian yang dilontarkan oleh kaedah
@Async. - Pengendali ini membolehkan anda mencatat ralat, menghantar pemberitahuan atau melakukan tindakan pemulihan ralat yang lain.
- Bagi kaedah yang mengembalikan
Future, pengecualian dibungkus dalamFuturedan dilontarkan apabilafuture.get()dipanggil.
Kumpulan Utas Tersuai
Bagi aplikasi pengeluaran, amat penting untuk mengkonfigurasikan kumpulan utas (Executor) anda sendiri bagi @Async. Hal ini memberi anda kawalan terhadap sumber dan prestasi.
Anda mentakrifkan bean ThreadPoolTaskExecutor dan menentukan sifatnya:
corePoolSize: Bilangan minimum utas yang dikekalkan aktif.maxPoolSize: Bilangan maksimum utas yang boleh terkandung dalam kumpulan.queueCapacity: Kapasiti baris gilir bagi tugas yang menunggu untuk dilaksanakan.threadNamePrefix: Awalan bagi nama utas dalam kumpulan ini, berguna untuk pengelogan.
Anda kemudiannya boleh menentukan pelaksana yang hendak digunakan dengan @Async("executorBeanName").
package com.coddykit.async;
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 = "customAsyncExecutor")
public Executor customAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2); // Keep 2 threads always running
executor.setMaxPoolSize(5); // Allow up to 5 threads if demand is high
executor.setQueueCapacity(10); // Queue up to 10 tasks if all threads are busy
executor.setThreadNamePrefix("CustomAsync-"); // Helps identify threads in logs
executor.initialize();
return executor;
}
// To use this, you'd annotate your async method like this:
// @Async("customAsyncExecutor")
// public void myCustomAsyncMethod() { /* ... */ }
}Semakan Pantas Tak Segerak
Mari kita semak pemahaman anda tentang anotasi @Async Spring.
Ringkasan Pelajaran
Tahniah! Anda telah mempelajari asas pemprosesan tak segerak dengan @Async Spring Boot.
- Kita melihat bagaimana operasi segerak menyekat, manakala operasi tak segerak membolehkan pelaksanaan tanpa sekatan.
- Anotasi
@EnableAsyncmengaktifkan pemprosesan kaedah tak segerak. - Anotasi
@Asyncpada sesuatu kaedah memastikan kaedah itu berjalan dalam utas berasingan. - Untuk mengembalikan hasil daripada kaedah tak segerak, kita menggunakan
Future<T>. - Bean
ThreadPoolTaskExecutortersuai membolehkan kawalan terperinci terhadap tingkah laku kumpulan utas.
Seterusnya, kita akan mendalami baris gilir mesej, iaitu cara yang berkuasa untuk menyahgandingkan perkhidmatan dan mengendalikan komunikasi tak segerak pada skala yang lebih besar.
Pelajari Java dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 21
- Pelajaran
- 84
Soalan Lazim
Adakah pelajaran “Kaedah Tak Segerak dengan @Async” percuma?
Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Panduan Lengkap Spring Boot 4, termasuk “Kaedah Tak Segerak dengan @Async”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Panduan Lengkap Spring Boot 4 merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Kaedah Tak Segerak dengan @Async”?
Pelajari cara melaksanakan kaedah secara tak segerak menggunakan anotasi `@Async` Spring dan kumpulan utas. Anda berlatih Panduan Lengkap Spring Boot 4 menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Panduan Lengkap Spring Boot 4?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Panduan Lengkap Spring Boot 4 di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.
Berapa lamakah pelajaran “Kaedah Tak Segerak dengan @Async” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Panduan Lengkap Spring Boot 4 ini?
Ya. Setiap pelajaran Panduan Lengkap Spring Boot 4 menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Kaedah Tak Segerak dengan @Async
- Pengenalan kepada Baris Gilir Mesej
- Mengintegrasikan RabbitMQ/Kafka
- Menjadualkan Tugasan dengan @Scheduled