"Hello, Amigo! Kami mempunyai ubat penawar untuk semua penyakit. Seperti yang telah kita lihat, penukaran benang yang tidak terkawal adalah masalah."

"Mengapa benang itu sendiri tidak boleh memutuskan masa untuk beralih ke urutan seterusnya? Lakukan semua yang mereka perlu lakukan dan kemudian beri isyarat, «Saya sudah selesai!»?"

"Membiarkan benang itu sendiri mengawal pensuisan akan menjadi masalah yang lebih besar. Katakan anda mempunyai beberapa kod bertulis yang buruk, dan benang itu tidak pernah menyerahkan CPU. Pada zaman dahulu, ini adalah cara ia berfungsi. Dan ia adalah mimpi ngeri."

"Okay. Jadi apa penyelesaiannya?"

" Menyekat benang lain.  Beginilah ia berfungsi."

Ia menjadi jelas bahawa utas mengganggu antara satu sama lain apabila mereka cuba menggunakan objek dan/atau sumber yang dikongsi . Sama seperti yang kita lihat dalam contoh dengan output konsol: terdapat satu konsol dan semua output benang padanya. Ia kacau-bilau.

Jadi objek khas dicipta: mutex . Ia seperti papan tanda pada pintu bilik mandi yang bertulis «tersedia / diduduki» . Ia mempunyai dua keadaan: objek tersedia atau diduduki . Keadaan ini juga dipanggil «terkunci» dan «terkunci».

Apabila benang memerlukan objek dikongsi dengan benang lain, ia menyemak mutex yang dikaitkan dengan objek. Jika mutex dibuka kuncinya, maka benang akan menguncinya (tandakannya sebagai «diduduki») dan mula menggunakan sumber yang dikongsi. Selepas utas telah menjalankan perniagaannya, mutex dibuka kuncinya (ditandakan sebagai «tersedia»).

Jika benang mahu menggunakan objek dan mutex dikunci, maka benang tidur sementara ia menunggu. Apabila mutex akhirnya dibuka oleh benang yang menduduki, benang kami akan segera menguncinya dan mula berjalan. Analogi dengan tanda pintu bilik mandi adalah sempurna.

"Jadi bagaimana saya boleh bekerja dengan mutex? Adakah saya perlu mencipta objek khas?"

"Ia jauh lebih mudah daripada itu. Pencipta Java membina mutex ini ke dalam kelas Objek. Jadi anda tidak perlu menciptanya pun. Ia adalah sebahagian daripada setiap objek. Begini cara semuanya berfungsi:"

Kod Penerangan
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";

public void swap()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}
}
Kaedah swap menukar nilai pembolehubah name1 dan name2.

Apakah yang mungkin berlaku jika ia dipanggil daripada dua utas pada masa yang sama?

Pelaksanaan kod sebenar Kod utas pertama Kod utas kedua
String s1 = name1; //Ally
name1 = name2; //Lena
name2 = s1; //Ally

String s2 = name1; //Lena
name1 = name2; //Ally
name2 = s2; //Lena
String s1 = name1;
name1 = name2;
//other thread is running
name2 = s1;
//the thread waits until the mutex is unlocked

String s2 = name1;
name1 = name2;
//other thread is running
//other thread is running
name2 = s2;
Garisan bawah
Nilai pembolehubah telah ditukar dua kali, kembali ke tempat asalnya.

Beri perhatian kepada kata kunci  yang disegerakkan .

"Ya, apa maksudnya?"

"Apabila benang memasuki blok kod yang ditandakan sebagai disegerakkan, mesin Java segera mengunci mutek objek yang ditunjukkan dalam kurungan selepas perkataan disegerakkan. Tiada benang lain boleh memasuki blok ini sehingga utas kami meninggalkannya. Sebaik sahaja benang kami keluar blok yang ditanda disegerakkan, mutex dibuka kunci serta-merta dan secara automatik dan akan tersedia untuk diperolehi oleh benang lain."

Jika mutex telah diduduki, maka benang kita akan berhenti dan menunggu ia dibebaskan.

"Sangat mudah dan sangat elegan. Itu penyelesaian yang cantik."

"Ya. Tetapi apa yang anda fikir akan berlaku dalam kes ini?"

Kod Penerangan
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";

public void swap()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}

public void swap2()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}
}
Kaedah swap dan swap2 berkongsi mutex yang sama ( objek ini ).

Apakah yang berlaku jika satu thread memanggil kaedah swap dan satu lagi thread memanggil kaedah swap2?

"Memandangkan mutex adalah sama, utas kedua perlu menunggu sehingga utas pertama meninggalkan blok yang disegerakkan. Jadi tidak akan ada sebarang masalah dengan akses serentak."

"Syabas, Amigo! Itu jawapan yang betul!"

Sekarang saya ingin menunjukkan bahawa disegerakkan boleh digunakan untuk menandakan bukan sahaja blok kod, tetapi juga kaedah. Inilah maksudnya:

Kod Apa sebenarnya yang berlaku
class MyClass
{
private static String name1 = "Ally";
private static String name2 = "Lena";

public synchronized void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}

public static synchronized void swap2()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
class MyClass
{
private static String name1 = "Ally";
private static String name2 = "Lena";

public void swap()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}

public static void swap2()
{
synchronized (MyClass.class)
{
String s = name1;
name1 = name2;
name2 = s;
}
}