Artikel ini terutama mempelajari masalah terkait utas latar belakang di Java, sebagai berikut.
Saya belum pernah mendengarnya sebelumnya bahwa ada latar belakang utas di Java. Secara umum, JVM (Java Virtual Machine) umumnya mencakup dua jenis utas, yaitu utas pengguna dan utas latar belakang. Yang disebut utas daemon mengacu pada utas yang menyediakan layanan umum di latar belakang saat program berjalan, dan utas ini bukan bagian yang sangat diperlukan dari program. Oleh karena itu, ketika semua utas non-background berakhir, yaitu, ketika utas pengguna berakhir, program berakhir. Pada saat yang sama, itu akan membunuh semua utas latar dalam proses. Sebaliknya, selama utas non-background masih berjalan, program tidak akan berakhir. Lebih baik mengeksekusi main () daripada utas non-backend.
Berdasarkan fitur ini, ketika semua utas pengguna di jalan keluar mesin virtual dari berjalan, utas daemon tidak memiliki objek layanan, JVM keluar.
Ini dijelaskan dalam kode sumber JDK.
* Menandai utas ini sebagai {@linkplain #isdaemon daemon} utas
* atau utas pengguna. Mesin virtual java keluar saat satu -satunya
* Benang yang berjalan adalah semua utas daemon.
1. Kondisi untuk memulai utas latar belakang:
/*Metode setdaemon () harus dipanggil sebelum memulai utas untuk mengatur utas ini sebagai utas latar belakang. * Dalam program ini, setelah kami memasukkan string, utas utama akan berhenti berjalan* maka tidak ada utas untuk pengguna yang dapat berjalan dalam program. Jadi utas latar belakang akan dihentikan * JVM akan dihentikan, dan pembaca yang tertarik dapat mencobanya sendiri */DaemonRunner kelas publik mengimplementasikan runnable {@Override public void run () {while (true) {for (int i = 0; i <3; i ++) {System.out.println ("utas daemon"+i);} {{{void. utas baru (DaemonRunner baru ()); Daemon.setdaemon (true); Daemon.start (); pemindai S = pemindai baru (System.in); string string = s.nextline (); runtime.getRuntime (). AddshutdownHook (thread baru () {@override public void run () {) (overn {override public run () {) (overN. "{override public run () {) (). {Timeunit.milliseconds.sleep (50);} catch (InterruptedException e) {E.PrintStackTrace ();}}});}}2. Semua utas dimulai di utas latar belakang milik utas latar belakang. Meskipun Anda tidak secara eksplisit menentukan bahwa mereka adalah utas latar belakang, mereka memang utas latar belakang.
/* Anda dapat menentukan apakah utasnya adalah utas latar belakang dengan memanggil metode isdaemon (). Jika itu adalah utas latar belakang, * maka utas apa pun yang dibuatnya secara otomatis diatur ke utas latar belakang * Dalam contoh ini, utas daemon diatur ke mode latar belakang dan kemudian memperoleh banyak utas anak. Utas ini tidak diatur ke mode * latar belakang, tetapi mereka memang utas latar belakang. Kemudian, utas daemon memasuki loop tak terbatas dan memanggil metode hasil dalam loop* untuk menyerahkan kontrol ke utas lain atau proses*/kelas daemon mengimplementasikan runnable {private thread [] t = utas baru [10];@override public run () {for (int i = 0; i <t.length; i ++) {t [i = i = i <t.length; i ++) {t [i+t [i = i <i ne baru (i nEw nEw (i need; i need; i+i ++) {t [i+n need (i ne nEw (n need (nEw nEW; i nEwnET; Daemonspawn ()); t [i] .start (); System.out.println ("Daemonspawn" + i + "dimulai");} untuk (int i = 0; i <t.length; i ++) {System.out.println ("t [" + i + "] .isdaemon" + t [i]. {Thread.yield ();}}} class Daemonspawn mengimplementasikan runnable {@Override public void run () {while (true) {thread.yield ();}}} public class daemons {public static void main (string [] args) {thread d = thread baru (baru {public static void main (string [] args) {thread d = new thread (baru {public static void main (string [] args) {thread d = new thread (New Thread Daemon ()); d.setdaemon (true); d.start (); System.out.println ("d.isdaemon () =" + d.isdaemon ()); coba {timeunit.seconds.sleep (1); // biarkan utas di latar belakang startup mendapat waktu eksekusi tertentu. } catch (InterruptedException e) {E.PrintStackTrace ();}}}Hasil eksekusi akhir adalah sebagai berikut:
d.isdaemon () = true
Daemonspawn 0Started
Daemonspawn 1Started
Daemonspawn 2Started
Daemonspawn 3Started
Daemonspawn 4Started
Daemonspawn 5Started
Daemonspawn 6Started
Daemonspawn 7Started
Daemonspawn 8Started
Daemonspawn 9Started
T [0] .Isdaememontrue
T [1] .Isdaememontrue
T [2] .Isdaememontrue
T [3] .Isdaememontrue
T [4] .Isdaememontrue
T [5] .Isdaememontrue
T [6] .Isdaememontrue
T [7] .Isdaememontrue
T [8] .Isdaememontrue
T [9] .Isdaememontrue
3. Tentukan objek ThreadFactory dengan menentukan metode Executors.newCachedThreadPool() . Dengan cara ini, kami juga dapat mengatur utas yang ingin kami mulai sebagai utas latar belakang.
/* Dalam contoh ini, untuk konstruktor statis ini: Executors.newcachedThreadPool (DaemementThreadFactory ()* Kita dapat meneruskan objek ThreadFactory, sehingga kita dapat mengatur utas yang ingin kita mulai sebagai utas latar belakang ini* ini perlu dicatat. Thread (r); t.setdaemon (true); return t;}}/* Dalam contoh ini, dalam metode utama, metode biasa dalam metode utama akan disebut terlebih dahulu, "System.out.println (" semua dameon yang diaktifkan, saat ini akan dicetak. Baris utama akan mengakhiri menjalankan. ; DaememonFromFactory ());} System.out.println ("Semua dameons dimulai"); coba {timeunit.milliseconds.sleep (500);} catch (InterruptedException e) {e.printstacktrace ();}}}}Hasil output akhir adalah:
Semua Dameons dimulai
Thread [Thread-3,5, Main] concurrency.daemonfromfactory@56214c1
Thread [Thread-2,5, Main] concurrency.daemonfromfactory@5724147d
Thread [Thread-0,5, Main] concurrency.daemonfromfactory@144fe080
Thread [Thread-1,5, Main] concurrency.daemonfromfactory@104fa29e
Thread [Thread-8,5, Main] concurrency.daemonfromfactory@5b069a7f
Thread [Thread-9,5, Main] concurrency.daemonfromfactory@1a7288d1
Thread [Thread-7,5, Main] concurrency.daemonfromfactory@25144c3e
Thread [Thread-4,5, Main] concurrency.daemonfromfactory@288523d
Thread [Thread-6,5, Main] concurrency.daemonfromfactory@1edae2a8
Thread [Thread-5,5, Main] concurrency.daemonfromfactory@626007aa
Thread [Thread-3,5, Main] concurrency.daemonfromfactory@56214c1
Thread [Thread-2,5, Main] concurrency.daemonfromfactory@5724147d
Thread [Thread-6,5, Main] concurrency.daemonfromfactory@1edae2a8
Thread [Thread-5,5, Main] concurrency.daemonfromfactory@626007aa
Thread [Thread-4,5, Main] concurrency.daemonfromfactory@288523d
Thread [Thread-9,5, Main] concurrency.daemonfromfactory@1a7288d1
Thread [Thread-7,5, Main] concurrency.daemonfromfactory@25144c3e
Thread [Thread-8,5, Main] concurrency.daemonfromfactory@5b069a7f
Thread [Thread-1,5, Main] concurrency.daemonfromfactory@104fa29e
Thread [Thread-0,5, Main] concurrency.daemonfromfactory@144fe080
Thread [Thread-2,5, Main] concurrency.daemonfromfactory@5724147d
Thread [Thread-3,5, Main] concurrency.daemonfromfactory@56214c1
Thread [Thread-6,5, Main] concurrency.daemonfromfactory@1edae2a8
Thread [Thread-1,5, Main] concurrency.daemonfromfactory@104fa29e
Thread [Thread-0,5, Main] concurrency.daemonfromfactory@144fe080
Thread [Thread-7,5, Main] concurrency.daemonfromfactory@25144c3e
Thread [Thread-8,5, Main] concurrency.daemonfromfactory@5b069a7f
Thread [Thread-5,5, Main] concurrency.daemonfromfactory@626007aa
Thread [Thread-9,5, Main] concurrency.daemonfromfactory@1a7288d1
Thread [Thread-4,5, Main] concurrency.daemonfromfactory@288523d
Thread [Thread-2,5, Main] concurrency.daemonfromfactory@5724147d
Thread [Thread-3,5, Main] concurrency.daemonfromfactory@56214c1
Thread [Thread-8,5, Main] concurrency.daemonfromfactory@5b069a7f
Thread [Thread-7,5, Main] concurrency.daemonfromfactory@25144c3e
Thread [Thread-4,5, Main] concurrency.daemonfromfactory@288523d
Thread [Thread-6,5, Main] concurrency.daemonfromfactory@1edae2a8
Thread [Thread-1,5, Main] concurrency.daemonfromfactory@104fa29e
Thread [Thread-0,5, Main] concurrency.daemonfromfactory@144fe080
Thread [Thread-9,5, Main] concurrency.daemonfromfactory@1a7288d1
Thread [Thread-5,5, Main] concurrency.daemonfromfactory@626007aa
Thread [Thread-3,5, Main] concurrency.daemonfromfactory@56214c1
Thread [Thread-2,5, Main] concurrency.daemonfromfactory@5724147d
Thread [Thread-8,5, Main] concurrency.daemonfromfactory@5b069a7f
4. Pertama -tama, Anda harus menyadari bahwa jika utas pengguna tiba -tiba keluar, utas latar akan mengakhiri metode yang dijalankan tanpa menjalankan klausa akhirnya.
/* Ketika Anda memanggil program ini, Anda akan melihat bahwa klausa akhirnya tidak akan dieksekusi, tetapi jika Anda mengomentari panggilan ke setdaemon (), Anda akan melihat bahwa klausa* akhirnya akan dieksekusi.* Perilaku ini benar. Bahkan jika Anda tidak menginginkan perilaku ini berdasarkan janji yang akhirnya Anda berikan di depan Anda. Tapi ini masalahnya. Ketika utas non-background terakhir berakhir, utas latar belakang akan tiba-tiba berhenti. Karena begitu utama () keluar, JVM akan segera menutup semua * utas di latar belakang. Karena Anda tidak dapat menutup utas latar belakang dengan cara yang elegan, mereka bukan ide yang bagus. Eksekutor non-backend biasanya * cara yang lebih baik, karena semua tugas yang dikendalikan oleh pelaksana dapat ditutup pada saat yang sama. */class Adaemon mengimplementasikan runnable {@Override public void run () {System.out.println ("Mulai Adaemon"); coba {timeunit.seconds.sleep (1); } catch (InterruptedException e) {System.out.println ("Keluar via InterruptedException"); } akhirnya {System.out.println ("Ini harus selalu berjalan?"); }}} kelas publik DaemonsDontrunfinalally {public static void main (string [] args) {thread t = thread baru (baru adaemon ()); t.setdaemon (true); t.start (); }} Hasil output akhir adalah sebagai berikut:
Mulai Adaemon
Namun, jika situasinya menjadi situasi berikut, hasil output akan berbeda lagi:
kelas Adaemon mengimplementasikan runnable {@Override public void run () {System.out.println ("Mulai Adaemon"); coba {timeunit.seconds.sleep (1); } catch (InterruptedException e) {System.out.println ("Keluar via InterruptedException"); } akhirnya {System.out.println ("Ini harus selalu berjalan?"); }}} kelas publik DaemonsDontrunfinalally {public static void main (string [] args) {thread t = thread baru (baru adaemon ()); t.setdaemon (true); t.start (); coba {timeunit.seconds.sleep (1); } catch (InterruptedException e) {E.PrintStackTrace (); }}}Karena utas utama tidak tiba -tiba keluar, utas latar belakang mendapatkan waktu eksekusi selama utas utama tidur, jadi hasil cetak akhir adalah:
Mulai Adaemon
Ini harus selalu berjalan?
Di atas adalah semua konten dari artikel ini tentang analisis contoh latar belakang utas di Java, dan saya harap ini akan membantu semua orang. Teman yang tertarik dapat terus merujuk ke topik terkait lainnya di situs ini. Jika ada kekurangan, silakan tinggalkan pesan untuk menunjukkannya. Terima kasih teman atas dukungan Anda untuk situs ini!