Kata kunci yang disinkronkan menyatakan bahwa metode ini terkunci. Ini setara dengan apa pun utas mana (seperti utas A), saat menjalankan metode ini, Anda harus memeriksa apakah utas lain B (atau C, D, dll.) Menggunakan metode ini (atau metode sinkronisasi lain dari kelas ini). Jika demikian, tunggu utas B (atau C, D) yang menggunakan metode yang disinkronkan untuk menjalankan metode ini sebelum menjalankan metode ini. Jika tidak, kunci penelepon dan jalankan langsung. Ini termasuk dua penggunaan: metode yang disinkronkan dan blok yang disinkronkan.
Mekanisme sinkronisasi multi-threaded mengunci sumber daya sehingga pada saat yang sama, hanya satu utas yang dapat beroperasi, dan sinkronisasi digunakan untuk menyelesaikan masalah yang mungkin timbul ketika beberapa utas mengakses secara bersamaan.
Mekanisme sinkronisasi dapat diimplementasikan menggunakan kata kunci yang disinkronkan.
Ketika kata kunci yang disinkronkan memodifikasi metode, metode ini disebut metode sinkronisasi.
Ketika metode yang disinkronkan dieksekusi atau pengecualian terjadi, kunci akan secara otomatis dilepaskan.
Berikut ini adalah contoh untuk menganalisis penggunaan kata kunci yang disinkronkan.
1. Penggunaan kata kunci yang disinkronkan secara berbeda
Contoh Program 1
Public Class ThreadTest {public static void main (string [] args) {contoh contoh = contoh baru (); Thread t1 = utas baru (contoh); Thread t2 = utas baru1 (contoh); t1.start (); t2.start (); }} Contoh kelas {public disinkronkan void execute () {for (int i = 0; i <10; ++ i) {coba {thread.sleep (500); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println ("Halo:" + i); }}} class thread1 memperluas thread {contoh private; thread publik1 (contoh contoh) {this.example = contoh; } @Override public void run () {example.execute (); }} Apakah untuk mempersiapkan kata kunci yang disinkronkan dalam metode execute (), hasil eksekusi dari contoh program ini akan sangat berbeda.
Jika kata kunci yang disinkronkan tidak ditambahkan, dua utas mengeksekusi metode execute () secara bersamaan, dan output adalah dua kelompok bersamaan.
Jika kata kunci yang disinkronkan ditambahkan, satu set 0 hingga 9 akan menjadi output terlebih dahulu, dan kemudian set berikutnya akan menjadi output, menunjukkan bahwa kedua utas dieksekusi secara berurutan.
2. Situasi multi-threading dari berbagai metode
Ubah program dan tambahkan metode lain Execute2 () ke kelas contoh.
Kemudian tulis thread Thread Thread2. Metode run () dalam thread2 mengeksekusi execute2 (). Kedua metode dalam kelas contoh dimodifikasi oleh kata kunci yang disinkronkan.
Contoh Program 2
Public Class ThreadTest {public static void main (string [] args) {contoh contoh = contoh baru (); Thread t1 = utas baru (contoh); Thread t2 = new thread2 (contoh); t1.start (); t2.start (); }} contoh kelas {public disinkronkan void execute () {for (int i = 0; i <20; ++ i) {coba {thread.sleep ((long) math.random () * 1000); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println ("Halo:" + i); }} public disinkronkan void execute2 () {for (int i = 0; i <20; ++ i) {coba {thread.sleep ((long) math.random () * 1000); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println ("Dunia:" + i); }}} class thread1 memperluas thread {contoh private; thread publik1 (contoh contoh) {this.example = contoh; } @Override public void run () {example.execute (); }} class thread2 memperluas thread {contoh private contoh; thread publik2 (contoh contoh) {this.example = contoh; } @Override public void run () {example.execute2 (); }} Jika kata kunci yang disinkronkan dihapus, kedua metode tersebut dieksekusi secara bersamaan dan tidak memiliki pengaruh timbal balik.
Tetapi seperti yang tertulis dalam contoh subrutin, bahkan dua metode:
Hasil eksekusi selalu merupakan output dari satu utas dan kemudian eksekusi utas lain.
menjelaskan:
Jika suatu objek memiliki beberapa metode yang disinkronkan, dan utas telah memasukkan metode yang disinkronkan pada saat tertentu, maka utas lain tidak dapat mengakses metode objek yang disinkronkan sebelum metode dijalankan.
Kesimpulan:
Ketika kata kunci yang disinkronkan memodifikasi metode, metode ini disebut metode sinkronisasi.
Setiap objek di Java memiliki kunci, atau monitor. Ketika utas mengakses metode sinkronisasi suatu objek, objek terkunci, dan tidak ada utas lain yang dapat mengakses metode objek yang disinkronkan (di sini mengacu pada semua metode sinkronisasi, bukan hanya metode yang sama). Tidak sampai utas sebelumnya melengkapi metode eksekusi (atau melempar pengecualian), kunci objek dilepaskan, sehingga utas lain dapat mengakses metode yang disinkronkan dari objek lagi.
Perhatikan bahwa objek terkunci saat ini. Jika itu adalah objek yang berbeda, tidak ada hubungan pembatasan antara objek.
Saat mencoba membangun objek utas kedua dalam kode, objek contoh baru dilewatkan, maka tidak ada batasan antara eksekusi kedua utas tersebut.
3. Pertimbangkan metode sinkronisasi statis
Ketika metode yang dimodifikasi kata kunci yang disinkronkan juga dimodifikasi oleh statis, telah dikatakan sebelumnya bahwa metode sinkronisasi non-statis akan mengunci objek, tetapi metode statis bukan milik objek, tetapi kelas, dan akan mengunci objek kelas kelas di mana metode ini berada.
Tidak peduli berapa banyak objek yang dihasilkan kelas, mereka sesuai dengan objek kelas yang sama.
Contoh Program 3
Public Class ThreadTest {public static void main (string [] args) {contoh contoh = contoh baru (); Thread t1 = utas baru (contoh); // Bahkan jika objek yang berbeda dilewatkan di sini, sinkronisasi metode statis masih tidak memungkinkan banyak utas untuk dieksekusi pada saat yang sama. Contoh = contoh baru (); Thread t2 = new thread2 (contoh); t1.start (); t2.start (); }} Contoh kelas {public Synchronized static void execute () {for (int i = 0; i <20; ++ i) {coba {thread.sleep ((long) math.random () * 1000); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println ("Halo:" + i); }} public disinkronkan static void execute2 () {for (int i = 0; i <20; ++ i) {coba {thread.sleep ((long) math.random () * 1000); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println ("Dunia:" + i); }}} class thread1 memperluas thread {contoh private; thread publik1 (contoh contoh) {this.example = contoh; } @Override public void run () {example.execute (); }} class thread2 memperluas thread {contoh private contoh; thread publik2 (contoh contoh) {this.example = contoh; } @Override public void run () {example.execute2 (); }} Jadi jika itu adalah metode statis (execute () dan execute2 () keduanya memiliki kata kunci statis yang ditambahkan), bahkan jika objek contoh yang berbeda diteruskan ke dua utas, kedua utas tersebut masih dibatasi satu sama lain. Seseorang harus dieksekusi terlebih dahulu dan kemudian yang berikutnya.
Kesimpulan:
Jika metode yang disinkronkan adalah statis, ketika utas mengakses metode, tidak mengunci objek di mana metode yang disinkronkan berada, tetapi objek kelas yang sesuai dengan kelas di mana metode yang disinkronkan berada. Di Java, tidak peduli berapa banyak objek yang dimiliki kelas, objek ini akan sesuai dengan objek kelas yang unik. Oleh karena itu, ketika utas mengakses dua metode statis dan disinkronkan dari dua objek dari kelas yang sama, urutan eksekusi mereka juga berurutan, yaitu, satu utas menjalankan metode terlebih dahulu, dan utas lainnya dimulai setelah eksekusi selesai.
4. Blok yang disinkronkan
Metode penulisan blok yang disinkronkan:
disinkronkan (objek) {} Ini berarti bahwa utas akan mengunci objek objek saat dieksekusi. (Perhatikan bahwa objek ini dapat menjadi objek dari kelas apa pun, atau Anda dapat menggunakan kata kunci ini).
Dengan cara ini, Anda dapat menentukan objek yang terkunci sendiri.
Contoh Program 4
Public Class ThreadTest {public static void main (string [] args) {contoh contoh = contoh baru (); Thread t1 = utas baru (contoh); Thread t2 = new thread2 (contoh); t1.start (); t2.start (); }} contoh kelas {objek objek privat = objek baru (); public void execute () {disinkronkan (objek) {for (int i = 0; i <20; ++ i) {coba {thread.sleep ((long) math.random () * 1000); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println ("Halo:" + i); }}} public void execute2 () {disinkronkan (objek) {untuk (int i = 0; i <20; ++ i) {coba {thread.sleep ((long) math.random () * 1000); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println ("Dunia:" + i); }}}}} class thread1 memperluas thread {contoh private; thread publik1 (contoh contoh) {this.example = contoh; } @Override public void run () {example.execute (); }} class thread2 memperluas thread {contoh private contoh; thread publik2 (contoh contoh) {this.example = contoh; } @Override public void run () {example.execute2 (); }} Efek yang dicapai dengan contoh program 4 sama dengan contoh program 2. Kedua utas dieksekusi secara berurutan, bukan secara bersamaan. Ketika satu utas dieksekusi, objek objek terkunci, dan utas lainnya tidak dapat menjalankan blok yang sesuai.
Metode yang disinkronkan sebenarnya setara dengan membungkus semua pernyataan dalam metode ini dengan blok yang disinkronkan, dan kemudian melewati kata kunci ini dalam tanda kurung blok yang disinkronkan. Tentu saja, jika itu adalah metode statis, objek kelas perlu dikunci.
Mungkin hanya beberapa baris kode dalam suatu metode yang akan melibatkan masalah sinkronisasi utas, sehingga blok yang disinkronkan mengontrol akses beberapa utas lebih granular daripada metode yang disinkronkan. Hanya konten dalam blok yang disinkronkan yang tidak dapat diakses oleh beberapa utas secara bersamaan, dan pernyataan lain dalam metode ini masih dapat diakses oleh beberapa utas secara bersamaan (termasuk sebelum dan sesudah blok yang disinkronkan).
Catatan: Data yang dilindungi oleh disinkronkan harus bersifat pribadi.
Kesimpulan:
Metode yang disinkronkan adalah kontrol bersamaan berbutir kasar. Pada saat tertentu, hanya satu utas yang dapat menjalankan metode yang disinkronkan;
Blok yang disinkronkan adalah kontrol konkurensi berbutir halus, yang hanya menyinkronkan kode di blok. Kode lain yang terletak di metode dan selain blok yang disinkronkan dapat diakses oleh beberapa utas secara bersamaan.