"Halo, Amigo! Kemarin kita membahas manfaat dan kemudahan multithreading. Sekarang saatnya melihat kekurangannya. Dan, sayangnya, tidak sedikit."

Sebelumnya, kita melihat program sebagai sekumpulan objek yang memanggil metode satu sama lain. Sekarang semuanya menjadi sedikit lebih rumit. Suatu program lebih seperti sekumpulan objek yang memiliki beberapa "robot kecil" (utas) yang merayapinya dan menjalankan perintah yang terkandung dalam metode.

Interpretasi baru ini tidak membatalkan yang pertama. Mereka masih objek, dan mereka masih memanggil metode satu sama lain. Tetapi kita harus ingat bahwa ada beberapa utas, dan setiap utas melakukan tugas atau tugasnya sendiri-sendiri.

Sebuah program menjadi lebih rumit. Utas yang berbeda mengubah keadaan objek yang berbeda berdasarkan tugas yang mereka lakukan. Dan mereka bisa menginjak kaki satu sama lain.

Tapi hal terburuk terjadi jauh di dalam mesin Java. Seperti yang sudah saya katakan, keserentakan utas dicapai dengan fakta bahwa prosesor terus-menerus beralih dari satu utas ke utas lainnya. Itu beralih ke utas, bekerja selama 10 milidetik, beralih ke utas berikutnya, bekerja selama 10 milidetik, dan seterusnya. Dan di sinilah letak masalahnya: peralihan ini dapat terjadi pada saat yang paling tidak tepat. Pertimbangkan contoh ini:

Kode thread pertama Kode thread kedua
System.out.print ("Nick is");
System.out.print ("");
System.out.print ("15");
System.out.print ("");
System.out.print ("years old");
System.out.println ();
System.out.print ("Lena is");
System.out.print ("");
System.out.print ("21");
System.out.print ("");
System.out.print ("years old");
System.out.println ();
Apa yang kami harapkan akan ditampilkan
Nick berumur 15 tahun
Lena berumur 21 tahun
Eksekusi kode aktual Kode thread pertama Kode thread kedua
System.out.print ("Nick is");
System.out.print ("Lena is");
System.out.print (" ");
System.out.print (" ");
System.out.print ("15");
System.out.print ("21");
System.out.print (" ");
System.out.print (" ");
System.out.print ("years old");
System.out.println ();
System.out.print ("years old");
System.out.println ();
System.out.print ("Nick is");
//other thread is running
//other thread is running
System.out.print (" ");
System.out.print ("15");
//other thread is running
//other thread is running
System.out.print (" ");
System.out.print ("years old");
System.out.println ();
//other thread is running
//other thread is running
//other thread is running
System.out.print ("Lena is");
System.out.print (" ");
//other thread is running
//other thread is running
System.out.print ("21");
System.out.print (" ");
//other thread is running
//other thread is running
//other thread is running
System.out.print ("years old");
System.out.println ();
Apa yang sebenarnya ditampilkan
Nick is  Lena   berumur 15  21  tahun

Dan inilah contoh lainnya:

Kode Keterangan
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";
public void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
Metode swap swapnilai name1dan name2variabel.

Apa yang mungkin terjadi jika dipanggil dari dua utas sekaligus?

Eksekusi kode aktual Kode thread pertama Kode thread kedua
String s1 = name1; //Ally
name1 = name2; //Lena
String s2 = name1; //Lena(!)
name1 = name2; //Lena
name2 = s1; //Ally
name2 = s2; //Lena
String s1 = name1;
name1 = name2;
//other thread is running
//other thread is running
name2 = s1;
//other thread is running
//other thread is running
//other thread is running
String s2 = name1;
name1 = name2;
//other thread is running
name2 = s2;
Garis bawah
Kedua variabel memiliki nilai «Lena».
Objek «Ally» tidak berhasil. Itu hilang.

"Siapa yang mengira bahwa kesalahan seperti ini mungkin terjadi dengan operasi penugasan yang begitu sederhana?!"

"Ya, masalah ini ada solusinya. Tapi kita akan membicarakannya nanti - tenggorokanku kering."