Penjadwalan di Jakarta EE

1. Ikhtisar

Di artikel sebelumnya, kami mendemonstrasikan cara menjadwalkan tugas di Spring menggunakan@Jadwalanotasi. Dalam artikel ini, kami akan mendemonstrasikan cara mencapai hal yang sama dengan menggunakan layanan pengatur waktu di aplikasi Jakarta EE untuk setiap kasus yang disajikan di artikel sebelumnya.

2. Aktifkan Dukungan untuk Penjadwalan

Dalam aplikasi Jakarta EE, tidak perlu mengaktifkan dukungan untuk tugas berjangka waktu. Layanan pengatur waktu adalah layanan yang dikelola kontainer yang memungkinkan aplikasi memanggil metode yang dijadwalkan untuk kejadian berbasis waktu. Sebagai contoh, sebuah aplikasi mungkin harus menjalankan beberapa laporan harian pada jam tertentu untuk menghasilkan statistik.

Ada dua jenis pengatur waktu:

  • Pengatur waktu terprogram : layanan pengatur waktu dapat dimasukkan ke dalam kacang apa pun (kecuali kacang sesi yang stateful) dan logika bisnis harus ditempatkan dalam metode yang dianotasi dengan @Timeout . Pengatur waktu dapat diinisialisasi dengan metode yang dianotasi @PostConstruct dari kacang atau juga dapat diinisialisasi hanya dengan memanggil metode.
  • Timer otomatis : logika bisnis ditempatkan dalam metode apa pun yang dianotasi dengan @Schedule atau @Schedules . Pengatur waktu ini diinisialisasi segera setelah aplikasi dimulai.

Jadi mari kita mulai dengan contoh pertama kita.

3. Jadwalkan Tugas dengan Penundaan Tetap

Di Musim Semi, ini dilakukan hanya dengan menggunakan anotasi @Scheduled (fixedDelay = 1000) . Dalam hal ini, durasi antara akhir eksekusi terakhir dan awal eksekusi berikutnya ditetapkan. Tugas selalu menunggu hingga tugas sebelumnya selesai.

Melakukan hal yang persis sama di Jakarta EE sedikit lebih sulit dicapai karena tidak ada mekanisme bawaan serupa yang disediakan, namun skenario serupa dapat diterapkan dengan sedikit pengkodean tambahan. Mari kita lihat bagaimana ini dilakukan:

@Singleton public class FixedTimerBean { @EJB private WorkerBean workerBean; @Lock(LockType.READ) @Schedule(second = "*/5", minute = "*", hour = "*", persistent = false) public void atSchedule() throws InterruptedException { workerBean.doTimerWork(); } } 
@Singleton public class WorkerBean { private AtomicBoolean busy = new AtomicBoolean(false); @Lock(LockType.READ) public void doTimerWork() throws InterruptedException { if (!busy.compareAndSet(false, true)) { return; } try { Thread.sleep(20000L); } finally { busy.set(false); } } }

Seperti yang Anda lihat, pengatur waktu dijadwalkan untuk dipicu setiap lima detik. Namun, metode yang dipicu dalam kasus kami mensimulasikan waktu respons 20 detik oleh panggilan sleep () pada Thread saat ini .

Akibatnya, container akan terus memanggil doTimerWork () setiap lima detik tetapi kondisi yang diletakkan di awal metode, busy.compareAndSet (false, true), akan segera ditampilkan jika panggilan sebelumnya belum selesai. Dalam hal ini, kami memastikan bahwa tugas berikutnya akan dijalankan hanya setelah tugas sebelumnya selesai.

4. Jadwalkan Tugas dengan Tarif Tetap

Salah satu cara untuk melakukannya adalah dengan menggunakan layanan timer yang diinjeksi dengan menggunakan @Resource dan dikonfigurasi dalam metode yang dianotasi @PostConstruct . Metode yang dianotasi dengan @Timeout akan dipanggil saat pengatur waktu berakhir.

Seperti disebutkan di artikel sebelumnya, awal eksekusi tugas tidak menunggu selesainya eksekusi sebelumnya. Opsi ini harus digunakan ketika setiap eksekusi tugas bersifat independen. Cuplikan kode berikut membuat pengatur waktu yang menyala setiap detik:

@Startup @Singleton public class ProgrammaticAtFixedRateTimerBean { @Inject Event event; @Resource TimerService timerService; @PostConstruct public void initialize() { timerService.createTimer(0,1000, "Every second timer with no delay"); } @Timeout public void programmaticTimout(Timer timer) { event.fire(new TimerEvent(timer.getInfo().toString())); } }

Cara lain adalah dengan menggunakan anotasi @Scheduled . Dalam cuplikan kode berikut kami mengaktifkan pengatur waktu setiap lima detik:

@Startup @Singleton public class ScheduleTimerBean { @Inject Event event; @Schedule(hour = "*", minute = "*", second = "*/5", info = "Every 5 seconds timer") public void automaticallyScheduled(Timer timer) { fireEvent(timer); } private void fireEvent(Timer timer) { event.fire(new TimerEvent(timer.getInfo().toString())); } }

5. Jadwalkan Tugas dengan Penundaan Awal

Jika skenario kasus penggunaan Anda memerlukan pengatur waktu untuk memulai dengan penundaan, kami juga dapat melakukannya. Dalam hal ini Jakarta EE mengizinkan penggunaan layanan pengatur waktu. Mari kita lihat contoh di mana pengatur waktu memiliki penundaan awal 10 detik dan kemudian menyala setiap lima detik:

@Startup @Singleton public class ProgrammaticWithInitialFixedDelayTimerBean { @Inject Event event; @Resource TimerService timerService; @PostConstruct public void initialize() { timerService.createTimer(10000, 5000, "Delay 10 seconds then every 5 seconds timer"); } @Timeout public void programmaticTimout(Timer timer) { event.fire(new TimerEvent(timer.getInfo().toString())); } }

The createTimer Metode yang digunakan dalam sampel kami adalah menggunakan tanda tangan berikut c reateTimer (panjang initialDuration, intervalDuration panjang, info java.io.Serializable) di mana initialDuration adalah jumlah milidetik yang harus dilalui sebelum pemberitahuan waktu kadaluarsa pertama dan intervalDuration adalah jumlah milidetik yang harus berlalu di antara pemberitahuan kedaluwarsa pengatur waktu.

Dalam contoh ini, kami menggunakan initialDuration 10 detik dan intervalDuration lima detik. Tugas akan dijalankan untuk pertama kalinya setelah nilai initialDuration dan akan terus dijalankan sesuai dengan intervalDuration .

6. Jadwalkan Tugas Menggunakan Ekspresi Cron

Semua penjadwal yang telah kita lihat, baik terprogram maupun otomatis, mengizinkan penggunaan ekspresi cron. Mari kita lihat contohnya:

@Schedules ({ @Schedule(dayOfMonth="Last"), @Schedule(dayOfWeek="Fri", hour="23") }) public void doPeriodicCleanup() { ... }

Dalam contoh ini, metode doPeriodicCleanup () akan dipanggil setiap hari Jumat pukul 23:00 dan pada hari terakhir setiap bulan.

7. Kesimpulan

Pada artikel ini kami telah melihat berbagai cara untuk menjadwalkan tugas di lingkungan Jakarta EE menggunakan sebagai titik awal artikel sebelumnya di mana sampel dilakukan menggunakan Spring.

Contoh kode dapat ditemukan di repositori GitHub.