1. Masalah sinkron diangkat
Sinkronisasi utas adalah untuk mencegah kerusakan data ketika beberapa utas mengakses objek data.
Misalnya: kedua utas ThreadA dan ThreadB mengoperasikan objek FOO yang sama dan memodifikasi data pada objek FOO.
paket cn.thread; kelas publik foo {private int x = 100; publik int getx () {return x; } public int fix (int y) {x = x - y; mengembalikan x; }} paket cn.thread; kelas publik myRunnable mengimplementasikan runnable {private foo foo = new foo (); public static void main (string [] args) {myrunnable run = new myrunnable (); Thread ta = utas baru (jalankan, "thread-a"); Thread tb = utas baru (jalankan, "thread-b"); ta.start (); tb.start (); } public void run () {for (int i = 0; i <3; i ++) {this.fix (30); coba {thread.sleep (1); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println (thread.currentThread (). GetName () + ": nilai x dari objek FOO saat ini =" + foo.getx ()); }} public int fix (int y) {return foo.fix (y); }}Hasil Menjalankan:
Thread-B: Nilai X dari objek FOO saat ini = 40
Thread-A: Nilai x objek FOO saat ini = 40
Thread -B: Nilai x dari objek FOO saat ini = -20
Thread -A: Nilai x dari objek FOO saat ini = -20
Thread -B: Nilai x dari objek FOO saat ini = -80
Thread -A: Nilai x objek FOO saat ini = -80
Dari hasilnya, ditemukan bahwa nilai output seperti itu jelas tidak masuk akal. Alasannya adalah bahwa dua utas mengakses objek FOO tanpa kontrol dan memodifikasi data mereka.
Jika Anda ingin mempertahankan rasionalitas hasilnya, Anda hanya perlu mencapai satu tujuan, yaitu membatasi akses ke FOO, dan hanya satu utas yang dapat mengaksesnya sekaligus. Ini akan memastikan rasionalitas data dalam objek Foo.
Dalam kode Java spesifik, dua operasi perlu diselesaikan:
Identifikasi foo variabel x dari kelas sumber daya yang dikunjungi oleh persaingan sebagai pribadi;
Sinkronisasi kode yang memodifikasi variabel, dan gunakan kata kunci yang disinkronkan untuk menyinkronkan metode atau kode.
paket cn.thread; kelas publik foo2 {private int x = 100; publik int getx () {return x; } // Metode disinkronkan Int fix publik yang disinkronkan (int y) {x = x - y; System.out.println ("Thread" + Thread.CurrentThread (). GetName () + "Jalankan berakhir, kurangi" " + y +" ", nilai saat ini adalah:" + x); mengembalikan x; } // // Blok kode yang disinkronkan // Public int fix (int y) {// disinkronkan (this) {// x = x - y; // system.out.println ("thread" + thread.currentThread (). GetName () + "run end, redup," " + y // +", nilai saat ini: " paket cn.thread; kelas publik myrunnable2 {public static void main (string [] args) {myrunnable2 run = new myrunnable2 (); Foo2 foo2 = foo2 baru (); Mythread t1 = run.new mythread ("thread a", foo2, 10); Mythread t2 = run.new mythread ("thread b", foo2, -2); Mythread t3 = run.new mythread ("thread c", foo2, -3); Mythread t4 = run.new mythread ("thread d", foo2, 5); t1.start (); t2.start (); t3.start (); t4.start (); } class mythread memperluas utas {private foo2 foo2; / ** Nilai Saat Ini*/ Private Int Y = 0; Mythread (nama string, foo2 foo2, int y) {super (name); this.foo2 = foo2; this.y = y; } public void run () {foo2.fix (y); }}} Thread A Run berakhir, reduksi "10", nilai saat ini adalah: 90
Thread C berjalan dan berakhir, mengurangi "-3", nilai saat ini adalah: 93
Thread B berjalan di akhir, mengurangi "-2", nilai saat ini adalah: 95
Thread D berjalan dan berakhir, mengurangi "5", nilai saat ini adalah: 90
2. Sinkronisasi dan penguncian
1. Prinsip kunci
Setiap objek di Java memiliki kunci bawaan.
Ketika program berjalan pada metode sinkronisasi sinkronisasi non-statis, kunci yang terkait dengan instance saat ini dari kelas kode yang dieksekusi (contoh ini). Kunci yang memperoleh suatu objek juga disebut Acquiring Lock, mengunci objek, mengunci objek, atau menyinkronkan pada suatu objek.
Kunci objek hanya berfungsi ketika program berjalan ke metode sinkronisasi yang disinkronkan atau blok kode.
Hanya ada satu kunci untuk suatu objek. Jadi, jika utas memperoleh kunci, tidak ada utas lain yang dapat memperoleh kunci sampai utas pertama melepaskan (atau mengembalikan) kunci. Ini juga berarti bahwa tidak ada utas lain yang dapat memasukkan metode yang disinkronkan atau blok kode pada objek sampai kunci dilepaskan.
Melepaskan kunci berarti bahwa utas kunci keluar dari metode sinkronisasi yang disinkronkan atau blok kode.
Ada beberapa poin penting tentang penguncian dan sinkronisasi:
1) hanya metode yang dapat disinkronkan, tetapi variabel dan kelas tidak dapat disinkronkan;
2) setiap objek hanya memiliki satu kunci; Ketika datang ke sinkronisasi, apa yang harus jelas? Yaitu, pada objek mana yang disinkronkan?
3) Tidak perlu menyinkronkan semua metode di kelas. Kelas dapat memiliki metode sinkron dan asinkron.
4) Jika dua utas ingin menjalankan metode yang disinkronkan dalam satu kelas, dan dua utas menggunakan instance yang sama untuk memanggil metode ini, maka hanya satu utas yang dapat menjalankan metode pada satu waktu, dan yang lain perlu menunggu sampai kunci dilepaskan. Artinya: jika utas memperoleh kunci pada objek, tidak ada utas lain yang dapat memasukkan metode sinkronisasi apa pun di kelas (dari objek itu).
5) Jika utas memiliki sinkronisasi dan metode asinkron, metode asinkron dapat diakses secara bebas oleh beberapa utas tanpa dibatasi oleh kunci.
6) Saat utas tidur, tidak ada kunci yang dipegang akan dilepaskan.
7) Utas dapat memperoleh beberapa kunci. Misalnya, memanggil metode sinkronisasi objek lain dalam metode sinkronisasi satu objek akan memperoleh kunci sinkronisasi dari dua objek.
8) Sinkronisasi merusak konkurensi dan harus mempersempit rentang sinkronisasi sebanyak mungkin. Sinkronisasi tidak hanya dapat menyinkronkan seluruh metode, tetapi juga menyinkronkan beberapa blok kode dalam metode ini.
9) Saat menggunakan blok kode sinkronisasi, Anda harus menentukan objek mana yang akan disinkronkan, yaitu, kunci objek mana yang harus diperoleh. Misalnya:
public int fix (int y) {disinkronkan (ini) {x = x - y; } return x;} Tentu saja, metode sinkronisasi juga dapat ditulis ulang sebagai metode asinkron, tetapi fungsinya persis sama, misalnya:
Publik sinkronisasi int getx () {return x ++;} Dan
publik int getx () {disinkronkan (ini) {return x ++; }}Efeknya persis sama.
3. Sinkronisasi metode statis
Untuk menyinkronkan metode statis, kunci diperlukan untuk seluruh objek kelas, yang merupakan kelas ini (xxx.class).
Misalnya:
Public Static Synchronized int setName (nama string) {xxx.name = name;}
Setara dengan
public static int setName (nama string) {disinkronkan (xxx.class) {xxx.name = name; }}4. Apa yang terjadi jika utas tidak dapat memperoleh kunci
Jika utas mencoba memasukkan metode sinkron dan kuncinya telah ditempati, utas diblokir pada objek. Pada dasarnya, utas memasuki kumpulan objek dan harus menunggu di mana ia harus menunggu sampai kuncinya dilepaskan dan utas menjadi dapat dijalankan atau dijalankan lagi.
Saat mempertimbangkan pemblokiran, pastikan untuk memperhatikan objek mana yang digunakan untuk mengunci:
1. Utas yang menyebut metode sinkronisasi non-statis dalam objek yang sama akan saling memblokir. Jika itu adalah objek yang berbeda, setiap utas memiliki kunci objek sendiri, dan utas tidak saling mengganggu.
2. Benang yang menyebut metode sinkronisasi statis di kelas yang sama akan saling memblokir, dan semuanya terkunci pada objek kelas yang sama.
3. Metode sinkronisasi statis dan metode sinkronisasi non-statis tidak akan pernah saling memblokir, karena metode statis dikunci pada objek kelas, sedangkan metode non-statis dikunci pada objek kelas ini.
4. Untuk blok kode yang disinkronkan, Anda perlu melihat dengan jelas objek apa yang telah digunakan untuk mengunci (isi braket yang disinkronkan setelah disinkronkan). Thread yang disinkronkan pada objek yang sama akan saling memblokir, dan utas yang terkunci pada objek yang berbeda tidak akan pernah saling memblokir.
5. Kapan kebutuhan untuk menyinkronkan
Ketika beberapa utas akses data yang saling eksklusif (dapat ditukar) secara bersamaan, itu harus disinkronkan untuk melindungi data, memastikan bahwa kedua utas tidak memodifikasi dan mengubahnya pada saat yang sama.
Untuk data yang dapat diubah di bidang non-statis, metode non-statis biasanya diakses.
Untuk data yang dapat diubah dalam bidang statis, biasanya diakses menggunakan metode statis.
Masalahnya menjadi sangat rumit jika Anda perlu menggunakan bidang statis dalam metode non-statis, atau memanggil metode non-statis di bidang statis. Ini telah melebihi ruang lingkup ujian SJCP.
6. kategori keamanan utas
Ketika kelas disinkronkan dengan baik untuk melindungi datanya, kelas ini disebut "Thread-Safe".
Bahkan untuk kelas yang aman-utas, Anda harus sangat berhati-hati, karena utas yang beroperasi masih belum tentu aman.
7. Ringkasan Sinkronisasi Thread
1. Tujuan sinkronisasi utas adalah untuk melindungi kerusakan sumber daya ketika banyak utas mengakses sumber daya.
2. Metode sinkronisasi utas diimplementasikan melalui kunci. Setiap objek hanya memiliki satu kunci. Kunci ini dikaitkan dengan objek tertentu. Setelah utas memperoleh kunci objek, utas lain yang mengakses objek tidak lagi dapat mengakses metode sinkronisasi objek lainnya.
3. Untuk metode sinkronisasi statis, kunci adalah untuk kelas ini, dan objek kunci adalah objek kelas dari kelas ini. Kunci metode statis dan non-statis tidak saling mengganggu. Utas memperoleh kunci, dan ketika mengakses metode sinkronisasi pada objek lain dalam metode sinkronisasi, ia memperoleh dua kunci objek ini.
4. Untuk sinkronisasi, adalah kunci untuk selalu menyadari objek mana yang akan disinkronkan.
5. Saat menulis kelas yang aman, Anda harus selalu memperhatikan untuk membuat penilaian yang benar pada logika dan keamanan beberapa utas yang bersaing untuk mengakses sumber daya, menganalisis operasi "atom", dan memastikan bahwa utas lain tidak dapat mengakses sumber daya yang bersaing selama operasi atom.
6. Ketika beberapa utas menunggu kunci objek, utas yang belum memperoleh kunci akan diblokir.
7. Kebuntuan disebabkan oleh benang yang menunggu satu sama lain untuk mengunci, dan kemungkinan kejadian dalam kenyataan sangat kecil. Jika Anda benar -benar ingin menulis program kebuntuan, itu mungkin tidak mudah, haha. Namun, begitu program mati, program akan mati.
Tautan asli: http://www.cnblogs.com/linjiqin/p/3208843.html
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.