Saya membaca multi-threading di Java dan saya menemukan ini
Variabel lokal thread safe di Java.
Sejak itu saya telah memikirkan Bagaimana / Mengapa variabel lokal aman untuk thread.
Adakah yang bisa memberi tahu saya.
java
thread-safety
Anand
sumber
sumber
Jawaban:
Saat Anda membuat utas, tumpukannya akan dibuat sendiri. Dua utas akan memiliki dua tumpukan dan satu utas tidak pernah berbagi tumpukannya dengan utas lainnya.
Semua variabel lokal yang ditentukan dalam program Anda akan dialokasikan memori dalam tumpukan (Seperti yang dikomentari Jatin, memori di sini berarti, nilai referensi untuk objek dan nilai untuk tipe primitif) (Setiap metode yang dipanggil oleh utas membuat bingkai tumpukan pada tumpukannya sendiri). Segera setelah eksekusi metode diselesaikan oleh utas ini, bingkai tumpukan akan dihapus.
Ada kuliah bagus dari profesor Stanford di youtube yang dapat membantu Anda memahami konsep ini.
sumber
Variabel lokal disimpan di tumpukan masing-masing utas. Itu berarti variabel lokal tidak pernah dibagikan antar utas. Itu juga berarti bahwa semua variabel primitif lokal aman untuk thread.
public void someMethod(){ long threadSafeInt = 0; threadSafeInt++; }
Referensi lokal ke objek sedikit berbeda. Referensi itu sendiri tidak dibagikan. Namun, objek yang direferensikan tidak disimpan di tumpukan lokal setiap utas. Semua objek disimpan di heap bersama. Jika sebuah objek yang dibuat secara lokal tidak pernah lolos dari metode pembuatannya, itu adalah thread aman. Bahkan Anda juga bisa meneruskannya ke metode dan objek lain selama tidak ada metode atau objek ini yang membuat objek yang diteruskan tersedia untuk utas lain
sumber
Pikirkan metode seperti definisi fungsionalitas. Ketika dua utas menjalankan metode yang sama, mereka sama sekali tidak terkait. Mereka masing-masing akan membuat versinya sendiri untuk setiap variabel lokal, dan tidak akan dapat berinteraksi satu sama lain dengan cara apa pun.
Jika variabel tidak lokal (seperti variabel instance yang ditentukan di luar metode di tingkat kelas), variabel tersebut akan dilampirkan ke instance (bukan ke satu proses metode). Dalam kasus ini, dua utas yang menjalankan metode yang sama melihat satu variabel, dan ini tidak aman untuk utas.
Pertimbangkan dua kasus ini:
public class NotThreadsafe { int x = 0; public int incrementX() { x++; return x; } } public class Threadsafe { public int getTwoTimesTwo() { int x = 1; x++; return x*x; } }
Di bagian pertama, dua utas yang berjalan pada contoh yang sama
NotThreadsafe
akan melihat x yang sama. Ini bisa berbahaya, karena utas mencoba mengubah x! Yang kedua, dua utas yang berjalan pada contoh yang samaThreadsafe
akan melihat variabel yang sangat berbeda, dan tidak dapat saling memengaruhi.sumber
Setiap pemanggilan metode memiliki variabel lokalnya sendiri dan, jelas, pemanggilan metode terjadi dalam satu utas. Variabel yang hanya diperbarui dengan satu thread secara inheren aman untuk thread.
Namun , perhatikan baik-baik apa yang sebenarnya dimaksud dengan ini: hanya penulisan ke variabel itu sendiri yang aman untuk thread; memanggil metode pada objek yang dirujuk tidak secara inheren aman untuk thread . Hal yang sama berlaku untuk memperbarui variabel objek secara langsung.
sumber
Selain jawaban lain seperti Nambari.
Saya ingin menunjukkan bahwa Anda dapat menggunakan variabel lokal dalam metode tipe anoymous:
Metode ini dapat dipanggil di thread lain yang dapat mengganggu keamanan thread, jadi java memaksa semua variabel lokal yang digunakan dalam tipe anoymous untuk dideklarasikan sebagai final.
Pertimbangkan kode ilegal ini:
public void nonCompilableMethod() { int i=0; for(int t=0; t<100; t++) { new Thread(new Runnable() { public void run() { i++; //compile error, i must be final: //Cannot refer to a non-final variable i inside an //inner class defined in a different method } }).start(); } }
Jika java mengizinkan ini (seperti yang dilakukan C # melalui "closures"), variabel lokal tidak akan lagi menjadi threadsafe dalam semua keadaan. Dalam hal ini, nilai
i
di akhir semua utas tidak dijamin100
.sumber
Thread akan memiliki tumpukannya sendiri. Dua utas akan memiliki dua tumpukan dan satu utas tidak pernah berbagi tumpukannya dengan utas lainnya. Variabel lokal disimpan di tumpukan masing-masing utas. Itu berarti variabel lokal tidak pernah dibagikan antar utas.
sumber
Pada dasarnya Empat Jenis Penyimpanan Ada di java untuk menyimpan Informasi Kelas dan data:
Metode Area, Heap, JAVA Stack, PC
jadi Area metode dan Heap dibagikan oleh semua utas tetapi setiap utas memiliki JAVA Stack dan PC-nya sendiri dan itu tidak dibagikan oleh Thread lainnya.
Setiap metode di java adalah sebagai Stack frame. jadi, ketika satu metode dipanggil oleh thread yang stack frame dimuat pada JAVA Stack-nya. Semua variabel lokal yang ada di stack frame dan operan stack terkait tidak dibagikan oleh orang lain. PC akan memiliki informasi tentang instruksi selanjutnya untuk dieksekusi dalam kode byte metode. jadi semua variabel lokal AMAN.
@Weston juga memberikan jawaban yang bagus.
sumber
Hanya variabel lokal yang disimpan di tumpukan benang.
Variabel lokal yang
primitive type
(misalnya int, long ...) disimpan dithread stack
dan akibatnya - thread lain tidak memiliki akses ke sana.Variabel lokal yaitu
reference type
(penerusObject
) berisi dari 2 bagian - alamat (yang disimpan dithread stack
) dan objek (yang disimpan diheap
)class MyRunnable implements Runnable() { public void run() { method1(); } void method1() { int intPrimitive = 1; method2(); } void method2() { MyObject1 myObject1 = new MyObject1(); } } class MyObject1 { MyObject2 myObject2 = new MyObject2(); } class MyObject2 { MyObject3 myObject3 = MyObject3.shared; } class MyObject3 { static MyObject3 shared = new MyObject3(); boolean b = false; }
sumber