Saya membaca JavaDoc untuk Threadlocal di sini
https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ThreadLocal.html
dan dikatakan "Instance ThreadLocal biasanya adalah bidang statis pribadi di kelas yang ingin mengaitkan status dengan utas (misalnya, ID pengguna atau ID Transaksi)."
Tetapi pertanyaan saya adalah mengapa mereka memilih untuk membuatnya statis (biasanya) - membuat hal-hal agak membingungkan untuk memiliki status "per utas" tetapi bidangnya statis?
sumber
ThreadLocal
untuk menyimpan referensi ke hash-set yang memetakan objek ke instance per-thread.ThreadLocal
akan menyimpan data lokal-threadnya sendiri meskipunThreadLocal
instance tersebut ada di thread yang sama. Tidak selalu salah untuk melakukan itu - saya kira itu mungkin pola yang paling tidak populer dari keduanyaBuatlah menjadi statis atau jika Anda mencoba untuk menghindari bidang statis apa pun di kelas Anda - jadikan kelas itu sendiri tunggal dan kemudian Anda dapat dengan aman menggunakan tingkat instance ThreadLocal selama Anda memiliki tunggal itu tersedia secara global.
sumber
Tidak harus seperti itu. Yang penting adalah itu harus tunggal.
sumber
Alasannya adalah variabel diakses melalui penunjuk yang terkait dengan utas. Mereka bertindak seperti variabel global dengan cakupan utas, oleh karena itu statis adalah yang paling cocok. Ini adalah cara Anda mendapatkan status lokal utas dalam hal-hal seperti pthreads jadi ini mungkin hanya kecelakaan sejarah dan implementasi.
sumber
Penggunaan threadlocal pada instance per utas adalah jika Anda ingin sesuatu terlihat di semua metode objek dan membuatnya aman untuk utas tanpa menyinkronkan akses ke sana seperti yang Anda inginkan untuk bidang biasa.
sumber
Lihat ini , ini memberi pemahaman yang lebih baik.
Singkatnya,
ThreadLocal
objek bekerja seperti peta nilai kunci. SaatThreadLocal
get/set
metode pemanggilan thread , ia akan mengambil / menyimpan objek thread di kunci peta, dan nilai dalam nilai peta. Itulah mengapa utas yang berbeda memiliki salinan nilai yang berbeda (yang ingin Anda simpan secara lokal), karena utas tersebut berada di entri peta yang berbeda.Itulah mengapa Anda hanya membutuhkan satu peta untuk menyimpan semua nilai. Meskipun tidak perlu, Anda dapat memiliki beberapa peta (tanpa mendeklarasikan statis) untuk menyimpan setiap objek utas juga, yang, ini benar-benar berlebihan, itulah mengapa variabel statis lebih disukai.
sumber
static final ThreadLocal
variabel aman untuk benang.static
membuat variabel ThreadLocal tersedia di beberapa kelas untuk thread masing-masing saja. Ini semacam deklarasi variabel global dari variabel lokal thread masing-masing di beberapa kelas.Kami dapat memeriksa keamanan utas ini dengan contoh kode berikut.
CurrentUser
- menyimpan id pengguna saat ini di ThreadLocalTestService
- Layanan sederhana dengan metode -getUser()
untuk mengambil pengguna saat ini dari CurrentUser.TestThread
- kelas ini digunakan untuk membuat banyak utas dan mengatur id pengguna secara bersamaan.
.
.
Jalankan kelas utama TestThread. Keluaran -
Ringkasan analisis
main
eksekusi berakhir dan cetak pengguna saat ini sebagai "62",ForkJoinPool.commonPool-worker-1
eksekusi paralel berakhir dan cetak pengguna saat ini sebagai "87",ForkJoinPool.commonPool-worker-2
eksekusi paralel berakhir dan cetak pengguna saat ini sebagai "31",ForkJoinPool.commonPool-worker-3
eksekusi paralel berakhir dan cetak pengguna saat ini sebagai "81"Kesimpulan
Concurrent Threads dapat mengambil userid yang benar meskipun telah dinyatakan sebagai "ThreadLocal final statis"
sumber