Jika kita perlu menjalankan beberapa tugas waktu sederhana selama proses pemrograman kita, kita tidak perlu melakukan kontrol yang kompleks. Kami dapat mempertimbangkan menggunakan tugas waktu pengatur waktu di JDK untuk mencapainya. LZ berikut menganalisis timer timer Java berdasarkan prinsipnya, contoh dan cacat timer.
1. Pendahuluan
Di Java, tugas waktu yang lengkap perlu diselesaikan oleh kelas timer dan timertask. Beginilah cara mereka didefinisikan dalam API. Timer: Alat yang menggunakannya untuk mengatur tugas yang dilakukan oleh utas di utas latar belakang nanti. Tugas dapat dieksekusi sekali, atau mereka dapat dieksekusi berulang kali. Tugas yang dijadwalkan oleh Timertask: Timer sebagai tugas yang dijalankan atau diulang. Kami dapat memahami bahwa timer adalah alat timer yang digunakan untuk merencanakan untuk menjalankan tugas yang ditentukan dalam utas latar belakang, dan timertask kelas abstrak yang subkelasnya mewakili tugas yang dapat direncanakan dengan pengatur waktu.
Kelas Timer <BR /> Dalam timer kelas alat, empat metode konstruktor disediakan. Setiap konstruktor memulai utas timer. Pada saat yang sama, kelas pengatur waktu dapat memastikan bahwa beberapa utas dapat berbagi objek timer tunggal tanpa sinkronisasi eksternal, sehingga kelas timer aman. Namun, karena setiap objek timer sesuai dengan utas latar belakang tunggal, yang digunakan untuk menjalankan semua tugas timer secara berurutan, secara umum, waktu yang dihabiskan untuk pelaksanaan tugas utas kami harus sangat singkat. Namun, karena keadaan khusus, waktu pelaksanaan tugas pengatur waktu tertentu terlalu lama, sehingga akan "secara eksklusif" utas eksekusi tugas timer, dan semua utas selanjutnya harus menunggu untuk dieksekusi, yang akan menunda pelaksanaan tugas -tugas berikutnya dan membuat tugas -tugas ini menumpuk bersama -sama. Kami akan menganalisis situasi spesifik nanti.
Ketika program menginisialisasi timer, tugas waktu akan dieksekusi sesuai dengan waktu yang kami tetapkan. Timer menyediakan metode jadwal, yang memiliki banyak kelebihan beban untuk beradaptasi dengan situasi yang berbeda, sebagai berikut:
Jadwal (Tugas Timertask, Waktu Tanggal): Jadwalkan pelaksanaan tugas yang ditentukan pada waktu yang ditentukan.
Jadwal (Tugas Timertask, Tanggal Pertama kali, Periode Panjang): Jadwalkan tugas yang ditentukan untuk memulai eksekusi penundaan tetap berulang pada waktu yang ditentukan.
Jadwal (Tugas TimerTask, Penundaan Panjang): Menjadwalkan tugas yang ditentukan untuk dieksekusi setelah penundaan yang ditentukan.
Jadwal (Tugas TimerTask, penundaan lama, periode panjang): Jadwalkan tugas yang ditentukan untuk dieksekusi berulang kali ditunda setelah penundaan yang ditentukan.
Pada saat yang sama, metode jadwalFixEdrate juga kelebihan beban. Metode penjadwalanan jadwal sama dengan jadwal, tetapi fokusnya berbeda, dan perbedaannya dianalisis nanti.
JadwalFixedRate (Tugas TimerTask, Tanggal Pertama kali, Periode Panjang): Jadwalkan tugas yang ditentukan untuk dieksekusi berulang kali pada tarif tetap pada waktu yang ditentukan.
JadwalFixedRate (Tugas Timertask, Penundaan Long, Periode Panjang): Jadwalkan tugas yang ditentukan untuk memulai eksekusi dengan suku bunga tetap yang diulang setelah penundaan yang ditentukan.
Timertask
Kelas Timertask adalah kelas abstrak yang diatur oleh timer sebagai tugas yang dieksekusi atau diulang. Ini memiliki metode abstrak run (), yang digunakan untuk melakukan operasi yang akan dilakukan oleh tugas timer yang sesuai. Oleh karena itu, setiap kelas tugas tertentu harus mewarisi timertask dan kemudian mengganti metode run ().
Selain itu, ia memiliki dua metode yang tidak beragam:
Boolean Cancel (): Batalkan tugas timer ini.
Long TerjadwalExecutionTime (): Mengembalikan waktu eksekusi yang dijadwalkan dari eksekusi aktual terbaru dari tugas ini.
2. Contoh
2.1. Tentukan waktu tunda untuk menjalankan tugas waktu
kelas publik timerTest01 {timer timer; Public TimerTest01 (int time) {timer = new timer (); timer.schedule (TimertaskTest01 (), waktu * 1000); } public static void main (string [] args) {System.out.println ("Timer Begin ..."); TimerTEST01 baru (3); }} kelas publik TimerTaskTest01 memperluas timerTask {public void run () {System.out.println ("Time's Up !!!"); }} Hasil Menjalankan:
Cetak Pertama: Timer Mulai ...
Cetak dalam 3 detik: Waktu habis !!!
2.2. Jalankan tugas waktu pada waktu yang ditentukan
kelas publik timerTest02 {timer timer; public timerTest02 () {date time = getTime (); System.out.println ("Tentukan waktu waktu =" + waktu); timer = timer baru (); timer.schedule (TimertaskTest02 (waktu) baru; } GetTime Tanggal Publik () {Calendar Calendar = Calendar.GetInstance (); calendar.set (calendar.hour_of_day, 11); Calendar.set (Calendar.minute, 39); Calendar.set (Calendar.Second, 00); Tanggal Waktu = Calendar.GetTime (); waktu pengembalian; } public static void main (string [] args) {new timerTest02 (); }} kelas publik timerTaskTest02 memperluas timerTask {@Override public void run () {System.out.println ("Jalankan tugas utas pada waktu yang ditentukan ..."); }} Ketika waktu mencapai 11:39:00, tugas utas akan dieksekusi, tentu saja, itu akan dieksekusi bahkan jika lebih besar dari waktu itu! Lai Hasil eksekusi adalah:
Waktu yang ditentukan = Sel 10 Juni 11:39:00 CST 2014
Jalankan tugas utas pada waktu yang ditentukan ...
2.3. Setelah menunda waktu yang ditentukan, tugas waktu akan dieksekusi pada waktu interval yang ditentukan.
Kelas Publik TimerTest03 {Timer Timer; public timertest03 () {timer = timer baru (); timer.schedule (TimertaskTest03 baru (), 1000, 2000); } public static void main (string [] args) {new timerTest03 (); }} kelas publik TimerTaskTest03 memperluas timerTask {@Override public void run () {date date = tanggal baru (this.scheduledExecutiontime ()); System.out.println ("Waktu untuk melaksanakan utas ini adalah:" + tanggal); }} Hasil Menjalankan:
Waktu untuk mengeksekusi utas ini adalah: Sel 10 Jun 21:19:47 CST 2014
Waktu untuk mengeksekusi utas ini adalah: Sel 10 Jun 21:19:49 CST 2014
Waktu untuk mengeksekusi utas ini adalah: Sel 10 Jun 21:19:51 CST 2014
Waktu untuk mengeksekusi utas ini adalah: Sel 10 Jun 21:19:53 CST 2014
Waktu untuk mengeksekusi utas ini adalah: Sel 10 Jun 21:19:55 CST 2014
Waktu untuk mengeksekusi utas ini adalah: Sel 10 Jun 21:19:57 CST 2014
................
Untuk tugas utas ini, jika kita tidak menghentikan tugas, itu akan terus berjalan.
Untuk tiga contoh di atas, LZ hanya menunjukkannya secara singkat, dan tidak menjelaskan contoh metode penjadwalanan. Bahkan, metode ini sama dengan metode jadwal!
2.4. Menganalisis jadwal dan penjadwalan
1), Jadwal (Tugas TimerTask, Waktu Tanggal), Jadwal (Tugas TimerTask, Penundaan Panjang)
Untuk kedua metode, jika Jadwal yang Ditentukan Excutiontime <= SystemCurrentTime, tugas akan segera dieksekusi. Jadwal Excutiontime tidak akan berubah karena eksekusi tugas yang berlebihan.
2) Jadwal (Tugas Timertask, Tanggal Pertama kali, Periode Panjang), Jadwal (Tugas TimerTask, Penundaan Panjang, Periode Panjang)
Kedua metode ini sedikit berbeda dari dua di atas. Seperti yang disebutkan sebelumnya, tugas timer timer akan ditunda karena tugas sebelumnya dieksekusi untuk waktu yang lama. Dalam dua metode ini, waktu yang dijadwalkan dari setiap tugas yang dieksekusi akan berubah dengan waktu aktual dari tugas sebelumnya, yaitu, JadwalExecutionTime (n+1) = ReaclexecutionTime (n)+periode waktu. Dengan kata lain, jika tugas ke -n menyebabkan proses waktu eksekusi ini karena beberapa situasi, dan akhirnya SystemCurrentTime> = Jadwal ExecutionTime (n+1), ini adalah tugas N+1 dan tidak akan dieksekusi karena waktu. Ini akan menunggu tugas ke -n dieksekusi sebelum dieksekusi, maka ini pasti akan mengarah ke implementasi eksekusi N+2 yang dijadwalkan rilis dan perubahan, yaitu, JadwalExecutionTime (n+2) = ReaclexecutionTime (n+1)+periode waktu. Oleh karena itu, kedua metode ini lebih memperhatikan stabilitas waktu interval penyimpanan.
3) JadwalFixedRate (Tugas TimerTask, Tanggal Pertama kali, Periode Panjang), JadwalFixedRate (Tugas TimerTask, Penundaan Panjang, Periode Panjang)
Seperti yang disebutkan sebelumnya, fokus metode jadwal dan metode jadwal berbeda. Metode jadwal berfokus pada stabilitas waktu interval penghematan, sedangkan metode jadwalFixEdrate lebih fokus pada menjaga stabilitas frekuensi eksekusi. Mengapa Anda mengatakan demikian, alasannya adalah sebagai berikut. Dalam metode jadwal, keterlambatan tugas sebelumnya akan menyebabkan keterlambatan tugas waktu setelahnya, sedangkan metode jadwalFixedRate tidak. Jika waktu eksekusi dari tugas ke -n terlalu lama, SystemCurrentTime> = StorduledExecutionTime (n+1), tidak akan ada menunggu untuk menjalankan tugas n+1 segera. Oleh karena itu, metode perhitungan dari waktu eksekusi metode jadwalFixEdrate berbeda dari jadwal, tetapi jadwal executiontime (n) = firstExecutetime +n*periode, dan metode perhitungan akan tetap tidak berubah selamanya. Oleh karena itu, penjadwalanan lebih fokus lebih fokus pada menjaga frekuensi eksekusi stabil.
3. Cacat Timer
3.1. Cacat Timer
Timer Timer Can Time (menjalankan tugas pada waktu yang ditentukan), tunda (tunda tugas pada 5 detik), dan secara berkala menjalankan tugas (jalankan tugas pada 1 detik), tetapi timer memiliki beberapa kekurangan. Pertama -tama, dukungan Timer untuk penjadwalan didasarkan pada waktu absolut, bukan waktu relatif, sehingga sangat sensitif terhadap perubahan waktu sistem. Kedua, utas timer tidak akan menangkap pengecualian. Jika pengecualian yang tidak dicentang dilemparkan oleh Timertask, itu akan menyebabkan utas timer berakhir. Pada saat yang sama, timer tidak akan melanjutkan eksekusi utas, dan secara keliru akan percaya bahwa seluruh utas timer akan dibatalkan. Pada saat yang sama, Timertask, yang telah dijadwalkan belum dieksekusi, tidak akan lagi dieksekusi, dan tugas -tugas baru tidak dapat dijadwalkan. Oleh karena itu, jika Timertask melempar pengecualian yang tidak terkendali, timer akan menghasilkan perilaku yang tidak dapat diprediksi.
1) Cacat penundaan waktu manajemen timer <br /> timer sebelumnya hanya akan membuat satu tugas utas saat menjalankan tugas waktunya. Jika ada beberapa utas, jika salah satu utas menyebabkan waktu eksekusi tugas utas terlalu lama karena beberapa alasan, dan interval antara kedua tugas melebihi waktu di antara mereka, beberapa cacat akan terjadi:
Kelas Publik TimerTest04 {private timer timer; Mulai Panjang Publik; public timertest04 () {this.timer = new timer (); start = system.currentTimeMillis (); } public void timerOne () {timer.schedule (new timerTask () {public void run () {System.out.println ("TimerOne dipanggil, waktu:" + (System.currentTimeMillis () - start)); coba {thread.sleep (4000); // thread sleeps 3000 E.PrintStackTrace ();}}}}, 1000); } public void timertwo () {timer.schedule (timerKask baru () {public void run () {System.out.println ("TimerOne dipanggil, waktu:" + (System.currentTimeMillis () - start));}}, 3000); } public static void main (string [] args) melempar Exception {TimerTest04 test = new timerTest04 (); test.timerone (); test.timertwo (); }} Menurut pemikiran normal kami, Timertwo harus dieksekusi setelah 3s, dan hasilnya harus:
Timerone dipanggil, waktu: 1001
Timerone dipanggil, waktu: 3001
Tapi segalanya bertentangan dengan harapan saya. Timerone tidur (4000), tidur 4s, dan timer berada di dalam timer, yang menyebabkan waktu yang dibutuhkan waktuOone melebihi interval. Hasilnya:
Timerone dipanggil, waktu: 1000
Timerone dipanggil, waktu: 5000
2) Timer melempar cacat pengecualian
Jika TimerTask melempar runtimeException, timer akan menghentikan semua tugas. sebagai berikut:
Kelas Publik TimerTest04 {private timer timer; public timertest04 () {this.timer = new timer (); } public void timerOne () {timer.schedule (new timertask () {public void run () {throw runimeException baru ();}}, 1000); } public void timertwo () {timer.schedule (timerKask baru () {public void run () {System.out.println ("Akankah saya menjalankannya ??");}}, 1000); } public static void main (string [] args) {timerTest04 test = new timerTest04 (); test.timerone (); test.timertwo (); }} Hasil Menjalankan: Timerone melempar pengecualian, menyebabkan tugas timertwo berakhir.
Pengecualian dalam Thread "Timer-0" java.lang.runtimeException di com.chenssy.timer.timertest04 $ 1.run (timerTest04.java:25) di java.util.timerThread.mainloop (timer.java:555) di java.uverrread.averread.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.aver.
Untuk cacat Timer, kami dapat mempertimbangkan JadwalThreadPoolExecutor sebagai pengganti. Pengatur waktu didasarkan pada waktu absolut dan lebih sensitif terhadap waktu sistem, sedangkan JadwalThreadPoolExecutor didasarkan pada waktu relatif; Timer adalah utas tunggal secara internal, sedangkan JadwalThreadPoolExecutor adalah kumpulan utas secara internal, sehingga dapat mendukung eksekusi bersamaan dari beberapa tugas.
3.2. Ganti timer dengan jadwal executorservice
1) Selesaikan masalahnya:
kelas publik yang dijadwalkan executortest {swasta jadwal executorservice scheduexec; Mulai Panjang Publik; ScheduledExecutortest () {this.scheDuexec = executors.newscheduledThreadPool (2); this.start = system.currentTimeMillis (); } public void timerOne () {scheduexec.schedule (runnable baru () {public void run () {System.out.println ("Timerone, The Time:" + (System.CurrentTimeMillis () - Mulai)); coba {thread.sleep (4000);} catch (}} {{thread. }, 1000, timeunit.milliseconds); } public void timertwo () {scheduleExec.schedule (runnable baru () {public void run () {System.out.println ("Timertwo, The Time:" + (System.CurrentTimeMillis () - start));}, 2000, timeunit.milliseceCs () - start));}, 2000, timeunit.millisecss () - start));}, 2000, timeunit.millisecss ())); } public static void main (string [] args) {scheduledExecutortest test = new dijadwalkan executortest (); test.timerone (); test.timertwo (); }} Hasil Menjalankan:
Timerone, The Time: 1003
Timertwo, The Time: 2005
2) Selesaikan masalah dua
kelas publik yang dijadwalkan executortest {swasta jadwal executorservice scheduexec; Mulai Panjang Publik; ScheduledExecutortest () {this.scheDuexec = executors.newscheduledThreadPool (2); this.start = system.currentTimeMillis (); } public void timerOne () {scheduexec.schedule (runnable baru () {public void run () {lempar runtimeException baru ();}}, 1000, timeunit.milliseconds); } public void timertwo () {scheduleExec.scheduleAtFixedrate (runnable baru () {public void run () {System.out.println ("TimertWo yang dipanggil .....");}}, 2000.500, timeunit.milliseconds); } public static void main (string [] args) {scheduledExecutortest test = new dijadwalkan executortest (); test.timerone (); test.timertwo (); }} Hasil Menjalankan:
Timertwo dipanggil ... timertwo dipanggil ... timertwo dipanggil ... timertwo dipanggil ... timertwo dipanggil ... timertwo dipanggil ... timertwo dipanggil ... timertwo dipanggil ... timertwo dipanggil ... timertwo dipanggil ............ timertwo diminta ...............
Di atas adalah seluruh konten artikel ini. Ini semua tentang tugas waktu Java. Saya harap ini akan membantu pembelajaran Anda.