Artikel ini adalah ringkasan dari penggunaan dasar java multithreading.
Artikel ini akan menjelaskan penggunaan dasar java multithreading dari aspek -aspek berikut:
Cara menggunakan multithreading
Dua cara untuk memulai utas
Java menyediakan dua cara untuk menggunakan multi-threading. Salah satunya adalah menulis kelas untuk mewarisi utas, kemudian menimpa metode run, dan kemudian panggil metode start untuk memulai utas. Pada saat ini, kelas ini akan menjalankan kode dalam metode run dengan cara utas lain. Cara lain adalah dengan menulis kelas untuk mengimplementasikan antarmuka Runnable, kemudian mengimplementasikan metode antarmuka yang dijalankan, dan kemudian membuat objek utas, menggunakan kelas yang mengimplementasikan antarmuka Runnable sebagai parameter konstruksi, meneruskannya ke objek utas, dan akhirnya objek utas memanggil metode start.
Metode start di sini adalah metode dengan fungsi startup, yang secara internal memanggil kembali metode run. Oleh karena itu, hanya ketika metode start dipanggil akan utas lain akan dimulai, metode run akan dipanggil secara langsung, atau dijalankan di utas yang sama, daripada berjalan di utas lain
Selain itu, metode start hanya memberi tahu mesin virtual bahwa utas dapat dimulai, yang berarti bahwa utas dalam keadaan siap, tetapi itu tidak berarti bahwa panggilan untuk memulai akan segera berjalan. Ini membutuhkan menunggu JVM untuk memutuskan kapan harus menjalankan utas. Dengan kata lain, jika ada dua utas A dan B, panggilan M dimulai terlebih dahulu, dan panggilan B dimulai nanti, itu tidak berarti bahwa utas itu berjalan terlebih dahulu, dan utas B berjalan nanti. Ini semua ditentukan oleh JVM dan dapat dianggap sebagai startup acak.
Di bawah ini kami menggunakan kode aktual untuk menggambarkan dua cara untuk memulai utas:
Tipe pertama adalah warisan utas
Contoh Kelas Publik Extends Extends Thread {@Override public void run () {super.run (); System.out.println ("Ini adalah contoh yang diwarisi dari utas"); }}Kode uji dapat ditemukan di kelas ExampleThreadTest di direktori tes
Cara lain, mengimplementasikan antarmuka yang dapat dijalankan
Kelas Public Expeplerunable mengimplementasikan runnable {public void run () {System.out.println ("Ini adalah kelas yang mengimplementasikan antarmuka runnable"); }}Untuk kode uji, Anda dapat melihat kelas ExamplerUnableToBTest di direktori tes.
Bagaimana mendapatkan beberapa informasi tentang multithreading
Setelah memulai multi-threading, kami berharap dapat memperoleh beberapa informasi tentang utas yang dimulai melalui beberapa API. JDK memberi kami metode kelas utas untuk mendapatkan beberapa informasi tentang utas.
Dapatkan nama utasnya
Metode ini adalah metode internal utas, sehingga kita dapat memanggil metode ini dalam dua cara. Salah satunya adalah ketika kelas kami mewarisi utas untuk menggunakan multi-utas, kami dapat menggunakan ini untuk menyebutnya. Cara lain adalah dengan memanggil metode ini melalui thread.currentThread (). Namun, kedua metode ini berbeda dalam skenario penggunaan yang berbeda.
Mari kita lihat secara singkat penggunaan dua metode.
Thread pertama. CurrentThread () digunakan, kodenya adalah sebagai berikut:
Kelas Publik ExampleCurrentThread memperluas Thread {Public ExpeplecurrentThread () {System.out.println ("Cetak metode konstruktor:" + thread.currentThread (). getName ()); } @Override public void run () {super.run (); System.out.println ("Cetak metode run:" + thread.currentThread (). GetName ()); }}Kode tes adalah sebagai berikut:
Kelas Publik ExampleCurrentThreadTest memperluas testcase {public void testInit () melempar Exception {exampleCurrentThread thread = exampleCurrentThread (); } public void testRun () melempar Exception {exewleCurrentThread thread = exewleCurrentThread () baru; thread.start (); Thread.sleep (1000); }}Hasilnya adalah sebagai berikut:
Pencetakan Metode Konstruktor: Pencetakan Metode MainRun: Pencetakan Metode Konstruksi Thread-0: Utama
Mengapa kita menggunakan thread.currentThread () di dalam exampleCurrentThread untuk menampilkan bahwa metode konstruksi dicetak sebagai utama, karena thread.currentThread () mengembalikan informasi bahwa segmen kode dipanggil oleh utas itu. Jelas bahwa metode konstruksi dieksekusi oleh utas utama, dan metode run dieksekusi oleh utas yang kami mulai sendiri. Karena tidak dinamai, itu adalah thread-0 default.
Selanjutnya, kita melihat warisan dari utas dan menyebutnya dengan ini.
kelas publik ComplexCurrentThread memperluas Thread {Public ComplexCurrentThread () {System.out.println ("Begin ===================="); System.out.println ("thread.currentThread (). GetName =" + thread.currentThread (). GetName ()); System.out.println ("this.getName () =" + this.getName ()); System.out.println ("end ================================================);} @Override public void run () {super.run (); System.out.println (" run begin =====; System.out.println ("Thread.CurrentThread (). GetName =" + Thread.CurrentThread (). GetName ());Kode tes adalah sebagai berikut:
Public Class ComplexCurrentThreadTest memperluas testcase {public void testRun () melempar Exception {complexCurrentThread thread = new ComplexCurrentThread (); thread.setname ("ByHieg"); thread.start (); Thread.sleep (3000); }}Hasilnya adalah sebagai berikut:
begin===========Thread.currentThread().getName=mainthis.getName()=Thread-0end===================== Run begin========Thread.currentThread().getName=byhiegthis.getName()=byhiegrun end===========
Pertama -tama, saat membuat objek, konstruktor masih dieksekusi oleh utas utama, jadi thread.currentThread () mendapatkan nama utas utama, tetapi metode ini mengacu pada objek yang memanggil metode, yaitu, informasi utas dari ComplexCurrentThread. Belum ada setName, jadi itu adalah nama default. Maka metode run adalah baik thread.currentThread () atau ini mengembalikan informasi utas dengan set nama ByHieg.
Jadi thread.currentThread mengacu pada informasi utas yang secara khusus menjalankan blok kode ini. Konstruktor dieksekusi oleh Main, dan Metode Jalankan adalah utas mana yang dimulai dan utas mana yang dijalankan. Dari sudut pandang ini, informasi yang dapat didapat ini tidak akurat, karena jika kita menjalankan this.getName () dalam menjalankan, tetapi metode run dimulai oleh utas lain, kita tidak bisa mendapatkan informasi dari kota baru yang menjalankan metode run melalui ini .getName. Dan hanya kelas yang mewarisi utas yang dapat memiliki metode seperti GetName, yang merupakan bencana untuk bahasa fitur Java yang tidak memiliki banyak warisan. Untuk semua informasi tentang utas yang ingin kami dapatkan setelahnya, kami menggunakan thread.currentThread () untuk menghubungi API.
Dapatkan ID utas
Hubungi GetID untuk mendapatkan identifikasi utas yang unik. Ini sama dengan penggunaan getName di atas. Tidak ada yang bisa dikatakan. Anda dapat secara langsung melihat ContohidThread dan kelas uji Contoh IidTreadtest.
Tentukan apakah utas bertahan
Fungsi metode isAlive () adalah untuk menguji apakah utas aktif. Keadaan aktif yang disebut berarti bahwa utas telah dimulai tetapi belum diakhiri. Artinya, setelah utas dimulai, itu dianggap hidup.
Mari kita lihat contoh spesifik:
kelas publik alivethread memperluas utas {@Override public void run () {super.run (); System.out.println ("Apakah itu hidup dalam metode run" + "" + thread.currentThread (). IsAlive ()); }}Metode pengujian adalah sebagai berikut:
kelas publik alivethreadtest memperluas testcase {public void testRun () melempar Exception {alivethread thread = new Alivethread (); System.out.println ("begin ==" + thread.isalive ()); thread.start (); Thread.sleep (1000); System.out.println ("end ==" + thread.isalive ()); Thread.sleep (3000); }}Hasilnya adalah sebagai berikut:
mulai == apakah trueEnd dalam metode false == false
Kita dapat menemukan bahwa sebelum mulai, utas dianggap tidak diatasi, dan kemudian ketika berjalan, itu hidup. Ketika metode menjalankan dieksekusi, itu dianggap tidak diatasi.
Bagaimana cara menghentikan utas
Tentukan apakah utas telah diakhiri
JDK menyediakan beberapa metode untuk menentukan apakah utas diakhiri - terputus () dan terputus ()
Cara menghentikan utas
Ini adalah metode yang lebih penting dalam memperoleh informasi utas, karena ini terkait dengan metode penghentian utas. Izinkan saya berbicara tentang beberapa cara untuk mengakhiri utas:
Saya tidak akan berbicara tentang yang pertama, metode pemberhentian kedua () telah ditinggalkan karena alasan berikut dapat terjadi:
Untuk contoh tertentu, Anda dapat melihat stoplockthread dan kelas uji stoplockThreadtest
Tipe ketiga adalah metode terminasi yang saat ini direkomendasikan, memanggil interupsi, dan kemudian menentukan apakah akan berakhir dalam metode run. Ada dua cara untuk menilai penghentian. Salah satunya adalah metode statis yang terputus () dari kelas utas, dan yang lainnya adalah metode anggota utas terputus (). Ada perbedaan antara kedua metode ini. Metode pertama akan secara otomatis mengatur ulang status. Jika terputus () dipanggil dua kali berturut -turut, jika itu salah pertama kali, kedua kalinya itu harus benar. Dan IsInterrupted () tidak akan.
Contohnya adalah sebagai berikut:
Contoh Public ClassInterread memperluas utas {@Override public void run () {super.run (); coba {untuk (int i = 0; i <50000000; i ++) {if (interrupted ()) {System.out.println ("Ini sudah merupakan status berhenti, saya ingin keluar"); lempar interupsi baru ("Berhenti ......"); } System.out.println ("i =" + (i + 1)); }} catch (InterruptedException e) {System.out.println ("Stop Smallly"); }}}Kode tes adalah sebagai berikut:
Contoh kelas publik InterruptThreadTest memperluas testcase {public void testRun () melempar Exception {exampleintertread thread = new ExpelInterruptThread (); thread.start (); Thread.sleep (1000); thread.interrupt (); }}Metode keempat sama dengan yang ketiga. Satu -satunya perbedaan adalah mengganti pengecualian yang dilemparkan dalam kode di atas dengan pengembalian. Saya masih suka melempar pengecualian. Ada banyak bentuk pemrosesan di sini, seperti mencetak informasi, menutup atau menangkap sumber daya dan kemudian melemparkannya ke lapisan atas lagi.
Perhatikan bahwa pengecualian yang kami lakukan di atas adalah Exception yang terganggu. Di sini kami secara singkat berbicara tentang alasan mengapa pengecualian ini dapat dihasilkan. Dalam hal tidur utas asli, hubungi interrupt untuk mengakhiri utas, atau mengakhiri utas terlebih dahulu dan kemudian membiarkan utas tidur.
Cara menjeda utas
Dua metode berikut disediakan di JDK untuk menjeda benang dan memulihkan utas.
Kedua metode ini adalah metode yang ditinggalkan seperti metode berhenti, dan penggunaannya sama dengan berhenti, menangguhkan benang dan memulihkan utas. Alasan utama mengapa kedua metode ini ditinggalkan adalah:
Beberapa penggunaan utas lainnya
Beberapa penggunaan dasar utas lainnya adalah sebagai berikut:
Konsesi utas
JDK menyediakan metode hasil () untuk membuat utas menyerahkan sumber daya CPU saat ini dan memberikannya kepada tugas -tugas lain untuk menempati waktu CPU, tetapi ini juga merupakan hal yang acak. Ada kemungkinan bahwa itu akan memakan waktu tepat setelah melepaskan sumber daya.
Untuk contoh spesifik, silakan merujuk ke ExampleyieldThread dan kelas uji ExampleyieldThreadtest
Atur prioritas utas
Kami dapat menetapkan prioritas utas untuk membiarkan CPU sebanyak mungkin untuk mengirim sumber daya eksekusi ke utas dengan prioritas yang lebih tinggi. Java menetapkan 1-10 10 level prioritas, dan ada tiga variabel statis untuk memberikan tiga tingkat prioritas:
/*** Prioritas minimum yang dapat dimiliki oleh utas. */ public static static int min_priority = 1; /*** Prioritas default yang ditetapkan ke utas. */ public static int int norm_priority = 5; /*** Prioritas maksimum yang dapat dimiliki oleh utas. */ public static int int max_priority = 10;
Kita dapat mengatur prioritas utas melalui setPriority, dan dapat langsung melewati tiga variabel statis untuk banding, atau langsung lulus dalam angka 1-10. Setelah pengaturan, utas akan memiliki prioritas yang berbeda. Apa yang terjadi jika kita tidak menetapkan prioritas?
Prioritas utas diwarisi. Jika kita memulai utas B di utas A, AB memiliki prioritas yang sama. Secara umum, ketika kami memulai utas di utas utama, kami memiliki prioritas yang konsisten dengan utas utama. Prioritas utas utama adalah 5 secara default.
Berikut beberapa aturan untuk prioritas:
Penjaga benang
JDK menyediakan metode setdaemon untuk mengatur utas menjadi benang daemon. Karakteristik benang daemon adalah bahwa setelah utas non-daemon lainnya dieksekusi, benang daemon akan dihancurkan secara otomatis. Contoh khas adalah pendaur ulang GC.
Untuk detailnya, Anda dapat melihat exampledaememonthread dan exampledaememementThreadtest.
Meringkaskan
Artikel ini terutama merangkum beberapa penggunaan dasar utas Java, dan termasuk dalam artikel kedua tentang keselamatan dan sinkronisasi utas.
Di atas adalah semua konten artikel ini. Saya berharap konten artikel ini akan membantu untuk belajar atau bekerja semua orang. Saya juga berharap untuk mendukung wulin.com lebih lanjut!