Panduan Lengkap Spring Boot 4 · Pelajaran

Kaedah Tak Segerak dengan @Async

Pelajari cara melaksanakan kaedah secara tak segerak menggunakan anotasi `@Async` Spring dan kumpulan utas.

Pelajaran 1 daripada 411 langkah

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 @Async selesai.
  • 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 @Async dipanggil, 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 @Async mengembalikan Future<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 dalam Future dan dilontarkan apabila future.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 @EnableAsync mengaktifkan pemprosesan kaedah tak segerak.
  • Anotasi @Async pada sesuatu kaedah memastikan kaedah itu berjalan dalam utas berasingan.
  • Untuk mengembalikan hasil daripada kaedah tak segerak, kita menggunakan Future<T>.
  • Bean ThreadPoolTaskExecutor tersuai 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.

Percuma untuk bermula

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

  1. Kaedah Tak Segerak dengan @Async
  2. Pengenalan kepada Baris Gilir Mesej
  3. Mengintegrasikan RabbitMQ/Kafka
  4. Menjadualkan Tugasan dengan @Scheduled
← Kembali ke Panduan Lengkap Spring Boot 4