Analisis paling komprehensif dari penggunaan multithreading Java. Jika Anda belum melakukan penelitian mendalam tentang mekanisme multithreading Java, maka artikel ini dapat membantu Anda lebih memahami prinsip dan metode penggunaan java multithreading.
1. Buat utas
Ada dua cara untuk membuat utas di java: menggunakan kelas utas dan menggunakan antarmuka runnable. Saat menggunakan antarmuka Runnable, Anda perlu membuat instance utas. Oleh karena itu, apakah Anda membuat utas melalui kelas utas atau antarmuka yang dapat dijalankan, Anda harus membuat contoh kelas utas atau subkelasnya. Konstruktor Thread:
Metode 1: mewarisi kelas utas dan menimpa metode run
Public Class ThreadDemo1 {public static void main (string [] args) {demo d = demo baru (); d.start (); untuk (int i = 0; i <60; i ++) {System.out.println (thread.currentThread (). getName ()+i); }}} Demo kelas memperluas thread {public void run () {for (int i = 0; i <60; i ++) {System.out.println (thread.currentThread (). getName ()+i); }}}Metode 2:
Public Class ThreadDemo2 {public static void main (string [] args) {demo2 d = new demo2 (); Utas t = utas baru (D); t.start (); untuk (int x = 0; x <60; x ++) {System.out.println (thread.currentThread (). getName ()+x); }}} class demo2 mengimplementasikan runnable {public void run () {for (int x = 0; x <60; x ++) {System.out.println (thread.currentThread (). getName ()+x); }}}2. Siklus hidup utas
Sama seperti orang yang lahir, usia tua, penyakit dan kematian, benang juga harus melalui empat negara bagian yang berbeda: mulai (tunggu), lari, menangguhkan dan berhenti. Keempat negara dapat dikontrol dengan metode di kelas utas. Berikut ini adalah metode yang terkait dengan keempat status ini di kelas utas.
// Mulai utas
PublicVoid Start ();
publicvoid run ();
// Tangguhkan dan bangun utas
publicvoid resume (); // tidak disarankan untuk menggunakan
PublicVoid Suspend (); // tidak disarankan untuk menggunakan
publicstaticvoid sleep (long millis);
publicstaticvoid sleep (long millis, int nanos);
// Akhiri utas
Publicvoid stop (); // tidak disarankan untuk menggunakan
PublicVoid Interrupt ();
// Dapatkan status utas
PublicBoolean Isalive ();
PublicBoolean terputus ();
PublicstaticBoolean interupsi ();
// Bergabunglah dengan metode
publicvoid gabungan () melempar interruptedException;
Setelah utas ditetapkan, itu tidak menjalankan kode dalam metode run segera, tetapi dalam keadaan menunggu. Ketika utas dalam keadaan menunggu, Anda dapat menggunakan metode kelas utas untuk mengatur berbagai properti utas, seperti prioritas utas (setPriority), nama utas (setName) dan tipe utas (setdaemon), dll.
Setelah menelepon metode start, utas mulai mengeksekusi kode dalam metode run. Utas memasuki keadaan berjalan. Anda dapat menggunakan metode isAlive dari kelas utas untuk menentukan apakah utas dalam keadaan berjalan. Ketika utas dalam keadaan berjalan, Isalive mengembalikan true. Ketika Isalive kembali salah, utas mungkin dalam keadaan menunggu atau dalam keadaan berhenti. Kode berikut menunjukkan switching antara tiga status membuat, menjalankan dan menghentikan utas, dan mengeluarkan nilai pengembalian isalive yang sesuai.
Setelah utas mulai mengeksekusi metode RUN, utas tidak akan keluar sampai metode run dieksekusi. Namun, selama pelaksanaan utas, utas dapat dihentikan sementara dengan dua metode. Kedua metode ini ditangguhkan dan tidur. Setelah menangguhkan utas dengan suspend, utas dapat dibangunkan melalui metode resume. Setelah menggunakan tidur untuk tidur, utas hanya dapat dimasukkan ke dalam keadaan siap setelah waktu yang ditentukan (setelah utas tidur, utas mungkin tidak segera dijalankan, tetapi hanya memasuki keadaan siap dan menunggu sistem untuk menjadwalkan).
Ada dua hal yang perlu diperhatikan saat menggunakan metode tidur:
1. Metode tidur memiliki dua formulir kelebihan beban. Salah satu formulir yang berlebihan tidak hanya dapat diatur ke milidetik, tetapi juga nanodetik (1.000.000 nanodetik sama dengan 1 milidetik). Namun, mesin virtual Java pada sebagian besar platform sistem operasi tidak dapat akurat untuk nanodetik, jadi jika nanodetik ditetapkan untuk tidur, mesin virtual Java akan membawa milidetik terdekat dengan nilai ini.
2. Saat menggunakan metode tidur, Anda harus menggunakan lemparan atau mencoba {...} catch {...}. Karena metode run tidak dapat menggunakan lemparan, Anda hanya dapat menggunakan coba {...} catch {...}. Saat utas sedang tidur, tidur akan melempar pengecualian Exceptedception saat mengganggu utas menggunakan metode interupsi. Metode tidur didefinisikan sebagai berikut:
publicstaticvoid sleep (long millis) melempar interrupted exception
publicstaticvoid sleep (long millis, int nanos) melempar interrupted exception
Ada tiga cara untuk mengakhiri utas.
1. Gunakan bendera keluar untuk membuat utas keluar secara normal, yaitu, utas berakhir ketika metode run selesai.
2. Gunakan metode berhenti untuk secara paksa menghentikan utas (metode ini tidak dianjurkan karena berhenti sama dengan penangguhan dan resume, dan mungkin juga memiliki hasil yang tidak dapat diprediksi).
3. Gunakan metode interupsi untuk mengganggu utas.
1. Gunakan bendera keluar untuk mengakhiri utas
Ketika metode pengumpulan dieksekusi, utas akan keluar. Tapi terkadang metode run tidak pernah berakhir. Misalnya, menggunakan utas untuk mendengarkan permintaan klien dalam program server, atau tugas lain yang memerlukan pemrosesan loop. Dalam hal ini, tugas -tugas ini biasanya ditempatkan dalam loop, seperti saat loop. Jika Anda ingin loop berjalan selamanya, Anda dapat menggunakan sementara (true) {...} untuk menanganinya. Namun, jika Anda ingin membuat loop saat keluar dalam kondisi tertentu, cara yang paling langsung adalah dengan mengatur bendera tipe boolean dan mengontrol apakah loop whene keluar dengan mengatur bendera ini menjadi benar atau salah. Berikut adalah contoh penghentian utas menggunakan bendera keluar.
Fungsi metode gabungan adalah mengubah utas eksekusi asinkron menjadi eksekusi sinkron. Dengan kata lain, ketika metode start dari instance utas dipanggil, metode ini akan segera kembali. Jika nilai yang dihitung oleh utas ini perlu digunakan setelah metode start dipanggil, metode bergabung harus digunakan. Jika Anda tidak menggunakan metode bergabung, tidak dapat dijamin bahwa ketika pernyataan di balik metode start dieksekusi, utas akan dieksekusi. Setelah menggunakan metode gabungan, program tidak akan dieksekusi sampai utas keluar. Kode berikut menunjukkan penggunaan gabungan.
3. Masalah Keselamatan Multithreaded
Penyebab Masalah: Ketika beberapa pernyataan beroperasi pada utas yang sama untuk berbagi data, satu utas hanya mengeksekusi bagian dari beberapa pernyataan, tetapi belum selesai mengeksekusi, dan utas lain berpartisipasi dalam eksekusi, menghasilkan kesalahan dalam berbagi data.
Solusi: Untuk beberapa pernyataan yang berbagi data dengan beberapa operasi, hanya satu utas yang dapat dieksekusi. Selama proses eksekusi, utas lain tidak mengeksekusi.
Sinkronisasi Blok Kode:
Public Class ThreadDemo3 {public static void main (string [] args) {ticket t = new ticket (); Thread t1 = utas baru (t, "window one"); Thread t2 = utas baru (t, "jendela dua"); Thread t3 = utas baru (t, "jendela tiga"); Thread t4 = utas baru (t, "window four"); t1.start (); t2.start (); t3.start (); t4.start (); }} Tiket kelas mengimplementasikan runnable {private int ticket = 400; public void run () {while (true) {disinkronkan (objek baru ()) {coba {thread.sleep (1); } catch (InterruptedException E) {// TODO Auto-Encanerated Catch Block E.PrintStackTrace (); } if (tiket <= 0) break; System.out.println (thread.currentThread (). GetName ()+"--- jual"+tiket--); }}}}Fungsi sinkron
Public Class ThreadDemo3 {public static void main (string [] args) {ticket t = new ticket (); Thread t1 = utas baru (t, "window one"); Thread t2 = utas baru (t, "jendela dua"); Thread t3 = utas baru (t, "jendela tiga"); Thread t4 = utas baru (t, "window four"); t1.start (); t2.start (); t3.start (); t4.start (); }} Class Ticket Implement Runnable {Private Int Ticket = 4000; public disinkronkan void saleticket () {if (tiket> 0) system.out.println (thread.currentThread (). getName ()+"dijual"+tiket--); } public void run () {while (true) {saleticket (); }}}Kunci fungsi sinkron adalah kunci fungsi sinkronisasi statis ini adalah kelas
Komunikasi antara utas
Public Class ThreadDemo3 {public static void main (string [] args) {class person {name public string; Jenis kelamin string pribadi; public void set (nama string, string gender) {this.name = name; this.gender = jenis kelamin; } public void get () {System.out.println (this.name+"...."+this.gender); }} orang terakhir p = orang baru (); utas baru (runnable baru () {public void run () {int x = 0; while (true) {if (x == 0) {p.set ("zhang san", "jantan");} else {p.set ("lili", "nv");} x = (x+1)%2;}}}). utas baru (runnable baru () {public void run () {while (true) {p.get ();}}}). start (); }}/ *Zhang san .... jantan zhang san .... jantan lili .... nvlili .... jantan zhang san .... nvlili .... jantan */Ubah kode di atas
Public Class ThreadDemo3 {public static void main (string [] args) {class person {name public string; Jenis kelamin string pribadi; public void set (nama string, string gender) {this.name = name; this.gender = jenis kelamin; } public void get () {System.out.println (this.name+"...."+this.gender); }} orang terakhir p = orang baru (); utas baru (runnable baru () {public void run () {int x = 0; while (true) {disinkronkan (p) {if (x == 0) {p.set ("zhang san", "jantan");} else {p.set ("lili", "nv");} x = (x+1)%2; utas baru (runnable baru () {public void run () {while (true) {disinkronkan (p) {p.get ();}}}}}). start (); }} /* lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv lili .... nv zhang san .... jantan zhang san zhang san .... jantan zhang san zhang san zhang san zhang san zhang jantan .... jantan san zhang san zhang san zhang san zhang san zhang san zhang san zhang san zhang san zhang san .... malhang san zhang san zhang san .... malhang san zhang jantan San .... Pria Zhang San .... Pria */Menunggu mekanisme bangun
/**Thread menunggu mekanisme bangun*Tunggu dan bangun harus menjadi kunci yang sama*/kelas publik threadDemo3 {private static boolean flags = false; public static void main (string [] args) {class person {name public string; Jenis kelamin string pribadi; public void set (nama string, string gender) {this.name = name; this.gender = jenis kelamin; } public void get () {System.out.println (this.name+"...."+this.gender); }} orang terakhir p = orang baru (); utas baru (runnable baru () {public void run () {int x = 0; while (true) {disinkronkan (p) {if (flags) coba {p.wait ();} catch (interruptedException e) {// todo auto catch block e.printstacktack (); {x == 0) {x == 0) (x == 0) {x == 0) {x == 0) {x == 0) {if (x); } else {p.set (lili "," nv "); utas baru (runnable baru () {public void run () {while (true) {disinkronkan (p) {if (! flags) coba {p.wait ();} catch (interruptedException e) {// tODO TODE Auto Catch Block E.PrintStackTrace ();}; p.) {p.) {) {) {p.) {) {p.) p. }).awal(); }}Mekanisme Produksi dan Konsumsi
Public Class ThreadDemo4 {private static boolean flags = false; public static void main (string [] args) {class goods {private string name; private int num; public disinkronkan void produce (nama string) {if (flags) coba {tunggu (); } catch (InterruptedException E) {// TODO Auto-Encanerated Catch Block E.PrintStackTrace (); } this.name = name+"Nomor:"+num ++; System.out.println ("Diproduksi ......"+this.name); bendera = true; notifyall (); } konsumsi void yang disinkronkan publik () {if (! Flags) coba {tunggu (); } catch (InterruptedException E) {// TODO Auto-Encanerated Catch Block E.PrintStackTrace (); } System.out.println ("dikonsumsi *****"+nama); bendera = false; notifyall (); }} barang akhir g = barang baru (); utas baru (runnable baru () {public void run () {while (true) {g.produce ("produk");}}}). start (); utas baru (runnable baru () {public void run () {while (true) {g.consume ();}}}). start (); }}Mekanisme Produksi dan Konsumsi 2
Public Class ThreadDemo4 {private static boolean flags = false; public static void main (string [] args) {class goods {private string name; private int num; void produce yang disinkronkan publik (nama string) {while (flags) coba {tunggu (); } catch (InterruptedException E) {// TODO Auto-Encanerated Catch Block E.PrintStackTrace (); } this.name = name+"Nomor:"+num ++; System.out.println (thread.currentThread (). GetName ()+"diproduksi ..."+this.name); bendera = true; notifyall (); } public disinkronkan void consume () {while (! flags) coba {tunggu (); } catch (InterruptedException E) {// TODO Auto-Encanerated Catch Block E.PrintStackTrace (); } System.out.println (thread.currentThread (). GetName ()+"dikonsumsi *******"+nama); bendera = false; notifyall (); }} barang akhir g = barang baru (); utas baru (runnable baru () {public void run () {while (true) {g.produce ("produk");}}}, "produk (" produk ");}}}," produce ("produk");}}, "produk (" produk ");}}}," produk "}; }, "Konsumen No. 1"). Start (); dikonsumsi ******* Nomor komoditas: 48050Producer No. 1 diproduksi ... Nomor komoditas: 48051Consumer No. 2 dikonsumsi **** Nomor komoditas: 48051Producer No. 48053Consumer No. 1 telah dikonsumsi ******* Nomor komoditas: 48053Producer No. 1 telah diproduksi ... Nomor komoditas: 48054Consumer No. 48055*/Di atas adalah kompilasi informasi multi-threaded Java. Kami akan terus menambahkan pengetahuan yang relevan di masa depan. Terima kasih atas dukungan Anda untuk situs web ini!