Komunikasi utas digunakan untuk memastikan operasi utas yang terkoordinasi. Secara umum, komunikasi utas perlu dipertimbangkan saat melakukan sinkronisasi utas.
1. Komunikasi utas tradisional
Biasanya, tiga metode yang disediakan oleh kelas ObjectLt digunakan:
Ketiga metode ini harus disebut oleh objek monitor sinkronisasi dan dibagi menjadi dua situasi:
Saat sinkronisasi metode, karena monitor sinkronisasi adalah objek ini, ketiga metode ini dapat dipanggil secara langsung.
Contohnya adalah sebagai berikut:
SyncMethodThreadCommunication kelas publik {static class dataWrap {int data = 0; bendera boolean = false; public disinkronkan void addThreada () {if (flag) {coba {tunggu (); } catch (InterruptedException e) {E.PrintStackTrace (); }} data ++; System.out.println (thread.currentThread (). GetName () + "" + data); bendera = true; memberitahu(); } public disinkronkan void addThreadB () {if (! flag) {coba {tunggu (); } catch (InterruptedException e) {E.PrintStackTrace (); }} data ++; System.out.println (thread.currentThread (). GetName () + "" + data); bendera = false; memberitahu(); }} class statis threada memperluas thread {private dataWrap data; threada publik (dataWrap dataWrap) {this.data = dataWrap; } @Override public void run () {for (int i = 0; i <10; i ++) {data.addThreada (); }}} kelas statis ThreadB memperluas utas {data private dataWrap; threadB publik (dataWrap dataWrap) {this.data = dataWrap; } @Override public void run () {for (int i = 0; i <10; i ++) {data.addthreadb (); }}} public static void main (string [] args) {// Implementasikan dua utas untuk menambahkan data secara giliran dataWrap dataWrap = new DataWrap (); threada baru (dataWrap) .start (); threadb baru (dataWrap) .start (); }}Saat menyinkronkan blok kode, Anda perlu menggunakan objek monitor untuk memanggil ketiga metode ini.
Contohnya adalah sebagai berikut:
Public Class SyncBlockThreadComminication {static class dataWrap {boolean flag; data int; } kelas statis threada memperluas thread {dataWrap dataWrap; threada publik (dataWrap dataWrap) {this.datawrap = dataWrap; } @Override public void run () {for (int i = 0; i <10; i ++) {disinkronkan (dataWrap) {if (dataWrap.flag) {coba {dataWrap.Wait (); } catch (InterruptedException e) {E.PrintStackTrace (); }} DataWrap.Data ++; System.out.println (getName () + "" + dataWrap.data); DataWrap.flag = true; DataWrap.Notify (); }}}}} kelas statis threadb memperluas utas {dataWrap dataWrap; threadB publik (dataWrap dataWrap) {this.datawrap = dataWrap; } @Override public void run () {for (int i = 0; i <10; i ++) {disinkronkan (dataWrap) {if (! DataWrap.flag) {coba {dataWrap.wait (); } catch (InterruptedException e) {E.PrintStackTrace (); }} DataWrap.Data ++; System.out.println (getName () + "" + dataWrap.data); datawrap.flag = false; DataWrap.Notify (); }}}} public static void main (string [] args) {// mengimplementasikan dua utas untuk menambahkan data secara giliran datawrap dataWrap = datawrap baru (); threada baru (dataWrap) .start (); threadb baru (dataWrap) .start (); }}2. Gunakan kondisi untuk mengontrol komunikasi utas
Saat menggunakan objek kunci untuk memastikan sinkronisasi, objek kondisi digunakan untuk memastikan koordinasi.
Contohnya adalah sebagai berikut:
impor java.util.concurrent.locks.condition; impor java.util.concurrent.locks.lock; impor java.util.concurrent.locks.reentrantlock; impor com.sun.media.sound.RiffinvaliddataException; impor javafx.scene.scene. SynclockThreadCommunication {static class dataWrap {int data; bendera boolean; kunci kunci final pribadi = reentrantlock baru (); kondisi kondisi akhir pribadi = lock.newcondition (); public void addThreada () {lock.lock (); coba {if (flag) {coba {condition.await (); } catch (InterruptedException e) {E.PrintStackTrace (); }} data ++; System.out.println (thread.currentThread (). GetName () + "" + data); bendera = true; condition.signal (); } akhirnya {lock.unlock (); }} public void addThreadB () {lock.lock (); coba {if (! flag) {coba {condition.await (); } catch (InterruptedException e) {E.PrintStackTrace (); }} data ++; System.out.println (thread.currentThread (). GetName () + "" + data); bendera = false; condition.signal (); } akhirnya {lock.unlock (); }}} kelas statis threada memperluas thread {dataWrap dataWrap; threada publik (dataWrap dataWrap) {this.datawrap = dataWrap; } @Override public void run () {for (int i = 0; i <10; i ++) {DataWrap.AddThreada (); }}} class statis ThreadB Extends Thread {DataWrap DataWrap; threadB publik (dataWrap dataWrap) {this.datawrap = dataWrap; } @Override public void run () {for (int i = 0; i <10; i ++) {DataWrap.AddThreadB (); }}} public static void main (string [] args) {// Implementasikan dua utas untuk menambahkan data secara giliran dataWrap dataWrap = new DataWrap (); threada baru (dataWrap) .start (); threadb baru (dataWrap) .start (); }}Await (), singal (), dan singalall () dari objek kondisi sesuai dengan tunggu (), notify () dan notifyall () metode masing -masing.
3. Gunakan blocking antreue blockingqueue untuk mengontrol komunikasi utas
BlockingQueue adalah sub-antarmuka antarmuka antrian, yang terutama digunakan untuk komunikasi utas. Ini memiliki fitur: Ketika utas produser mencoba memasukkan elemen ke dalam blockingqueue, jika antrian penuh, utas diblokir; Ketika utas konsumen mencoba mengeluarkan elemen dari blockingqueue, jika antrian kosong, utas diblokir. Dua fitur ini sesuai dengan dua metode yang mendukung pemblokiran, menempatkan (e e) dan take ()
Contohnya adalah sebagai berikut:
impor java.util.concurrent.arrayblockingqueue; impor java.util.concurrent.blockingqueue; blockingqueueethreadComminication {kelas statis datawrap {int data; } kelas statis threada memperluas thread {private blockingqueue <dateWrap> blockingqueue; threada publik (blockingqueue <datawrap> blockingqueue, nama string) {super (name); this.blockingqueue = blockingqueue; } @Override public void run () {for (int i = 0; i <100; i ++) {coba {dataWrap dataWrap = blockingqueue.take (); DataWrap.Data ++; System.out.println (getName () + "" + dataWrap.data); tidur (1000); } catch (InterruptedException e) {E.PrintStackTrace (); }}}}} kelas statis threadb memperluas thread {private blockingqueue <dateWrap> blockingqueue; DataWrap Private DataWrap; ThreadB publik (blockingqueue <datawrap> blockingqueue, dataWrap dataWrap, nama string) {super (name); this.blockingqueue = blockingqueue; this.datawrap = dataWrap; } @Override public void run () {for (int i = 0; i <100; i ++) {coba {dataWrap.data ++; System.out.println (getName () + "" + dataWrap.data); blockingqueue.put (dataWrap); tidur (1000); } catch (InterruptedException e) {E.PrintStackTrace (); }}}} public static void main (string [] args) {/// Imlementasikan dua utas untuk menambahkan data secara giliran dataWrap dataWrap = new DataWrap (); Blockingqueue <datawrap> blockingqueue = arrayblockingqueue baru <> (1); threada baru (blockingqueue, "konsumen"). start (); ThreadB baru (BlockingQueue, DataWrap, "Produser"). Start (); }}BlockingQueue memiliki lima kelas implementasi:
ArrayBlockingQueue Blockingqueue Antrian Berdasarkan Implementasi Array
LinkedBlockingQueue Blockingqueue Antrian Berdasarkan Daftar Tertaut
Elemen -elemen di PrioritasBlockingQueue perlu mengimplementasikan antarmuka yang sebanding, dan pemesanan elemen disesuaikan dengan pembanding.
Synchronousqueue menyinkronkan antrian, mengharuskan operasi akses pada antrian harus dilakukan secara bergantian.
Elemen pengumpulan delayqueue harus mengimplementasikan antarmuka penundaan, dan elemen -elemen dalam antrian diurutkan sesuai dengan nilai pengembalian metode antarmuka tunda getDelay ().
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.