Bagaimana untuk menggunakan kelas Java ThreadLocal
Seperti yang ditunjukkan dalam gambar:
Permulaan Pantas
Seterusnya, kami akan menggunakan contoh mudah untuk menunjukkan kepada anda penggunaan asas ThreadLocal
package cuit.pymjl.thradlocal; /** * @author Pymjl * @version 1.0 * @date 2022/7/1 10:56 **/ public class MainTest { static ThreadLocal<String> threadLocal = new ThreadLocal<>(); static void print(String str) { //打印当前线程中本地内存中本地变量的值 System.out.println(str + " :" + threadLocal.get()); //清除本地内存中的本地变量 threadLocal.remove(); } public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { @Override public void run() { //设置线程1中本地变量的值 threadLocal.set("thread1 local variable"); //调用打印方法 print("thread1"); //打印本地变量 System.out.println("after remove : " + threadLocal.get()); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { //设置线程1中本地变量的值 threadLocal.set("thread2 local variable"); //调用打印方法 print("thread2"); //打印本地变量 System.out.println("after remove : " + threadLocal.get()); } }); t1.start(); t2.start(); } }
Hasil larian adalah seperti yang ditunjukkan dalam rajah:
Prinsip ThreadLocal
Rajah kelas berkaitan ThreadLocal
Mari kita lihat dahulu struktur gambar rajah kelas kelas berkaitan ThreadLocal, sebagai ditunjukkan dalam rajah:
Seperti yang dapat dilihat daripada rajah ini, terdapat threadLocals dan inheritableThreadLocals dalam kelas ThreadLocalMap jenis, dan ThreadLocalMap ialah Hashmap tersuai. Secara lalai, kedua-dua pembolehubah ini dalam setiap utas adalah batal, dan ia dicipta hanya apabila utas semasa memanggil set atau dapatkan kaedah ThreadLocal untuk kali pertama. Sebenarnya, pembolehubah tempatan setiap utas tidak disimpan dalam contoh ThreadLocal, tetapi dalam pembolehubah threadLocals bagi utas panggilan. Dalam erti kata lain, pembolehubah tempatan jenis ThreadLocal disimpan dalam ruang memori benang tertentu. ThreadLocal ialah cangkerang alat yang meletakkan nilai ke dalam threadLocals pada utas panggilan melalui kaedah yang ditetapkan dan menyimpannya Apabila utas panggilan memanggil kaedah getnya, ia mengeluarkannya daripada pembolehubah threadLocals bagi utas semasa untuk digunakan. Jika utas panggilan tidak pernah ditamatkan, maka pembolehubah tempatan ini akan sentiasa disimpan dalam pembolehubah threadLocals bagi utas panggilan Oleh itu, apabila pembolehubah tempatan tidak diperlukan, anda boleh memadamkan pembolehubah tempatan daripada threadLocals bagi utas semasa dengan memanggil pembolehubah tempatan. alih keluar kaedah pembolehubah ThreadLocal. Selain itu, mengapakah threadLocals dalam Thread direka sebagai struktur peta? Jelas sekali kerana setiap utas boleh dikaitkan dengan berbilang pembolehubah ThreadLocal. Seterusnya, mari kita lihat kod sumber set ThreadLocal, dapatkan dan alih keluar
set
public void set(T value) { // 1.获取当前线程(调用者线程) Thread t = Thread.currentThread(); // 2.以当前线程作为key值,去查找对应的线程变量,找到对应的map ThreadLocalMap map = getMap(t); if (map != null) { // 3.如果map不为null,则直接添加元素 map.set(this, value); } else { // 4.否则就先创建map,再添加元素 createMap(t, value); } }
void createMap(Thread t, T firstValue) { /** * 这里是创建一个ThreadLocalMap,以当前调用线程的实例对象为key,初始值为value * 然后放入当前线程的Therad.threadLocals属性里面 */ t.threadLocals = new ThreadLocalMap(this, firstValue); }
ThreadLocalMap getMap(Thread t) { //这里就是直接获取调用线程的成员属性threadlocals return t.threadLocals; }
get
public T get() { // 1.获取当前线程 Thread t = Thread.currentThread(); // 2.获取当前线程的threadlocals,即ThreadLocalMap ThreadLocalMap map = getMap(t); // 3.如果map不为null,则直接返回对应的值 if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } // 4.否则,则进行初始化 return setInitialValue(); }
Berikut ialah kod setInitialValue
private T setInitialValue() { //初始化属性,其实就是null T value = initialValue(); //获取当前线程 Thread t = Thread.currentThread(); //通过当前线程获取ThreadLocalMap ThreadLocalMap map = getMap(t); //如果map不为null,则直接添加元素 if (map != null) { map.set(this, value); } else { //否则就创建,然后将创建好的map放入当前线程的属性threadlocals createMap(t, value); } //将当前ThreadLocal实例注册进TerminatingThreadLocal类里面 if (this instanceof TerminatingThreadLocal) { TerminatingThreadLocal.register((TerminatingThreadLocal<?>) this); } return value; }
Saya perlu menambah beberapa penjelasan tambahan di siniTerminatingThreadLocal
. Kelas ini baharu dalam jdk11 dan tidak wujud dalam jdk8, jadi tiada perihalan berkaitan kelas ini dalam banyak analisis kod sumber di Internet. Saya telah melihat kod sumber kelas ini, dan fungsinya adalah untuk mengelakkan masalah kebocoran memori ThreadLocal (jika anda berminat, anda boleh menyemak kod sumber, dan sila betulkan saya jika terdapat sebarang ralat). Ini ialah penjelasan rasmi:
/** * A thread-local variable that is notified when a thread terminates and * it has been initialized in the terminating thread (even if it was * initialized with a null value). * 一个线程局部变量, * 当一个线程终止并且它已经在终止线程中被初始化时被通知(即使它被初始化为一个空值)。 */
alih keluar
public void remove() { //如果当前线程的threadLocals 变量不为空, 则删除当前线程中指定ThreadLocal 实例的本地变量。 ThreadLocalMap m = getMap(Thread.currentThread()); if (m != null) { m.remove(this); } }
Ringkasan
Di dalam setiap utas, terdapat pembolehubah ahli bernama threadLocals, yang jenis Hash Map, dengan kuncinya rujukan ini bagi pembolehubah ThreadLocal yang kami takrifkan, dan nilai ialah nilai yang kami tetapkan menggunakan kaedah yang ditetapkan. Pembolehubah tempatan bagi setiap utas disimpan dalam utas pembolehubah memori sendiri. Jika utas semasa tidak pernah mati, pembolehubah tempatan ini akan sentiasa wujud, jadi ia boleh menyebabkan limpahan memori Oleh itu, ingat untuk memanggil kaedah alih keluar ThreadLocal untuk memadam gunakan. Pembolehubah setempat dalam threadLocals yang sepadan dengan thread.
Kebocoran memori ThreadLocal
Mengapa kebocoran memori berlaku?
ThreadLocalMap menggunakan rujukan ThreadLocal yang lemah sebagai kunci Jika ThreadLocal tidak mempunyai rujukan kuat luaran untuk merujuk kepadanya, maka ThreadLocal pasti akan dikitar semula semasa GC sistem , ThreadLocalMap akan Apabila Entri dengan kekunci null muncul , tiada cara untuk mengakses nilai Entri ini dengan kekunci null Jika urutan semasa tidak berakhir untuk masa yang lama, akan sentiasa ada menjadi garis yang kuat untuk nilai Entri ini dengan kunci null: Rujukan Benang -> Sebenarnya, keadaan ini telah diambil kira dalam reka bentuk ThreadLocalMap, dan beberapa langkah perlindungan telah ditambah: semua kekunci dalam thread ThreadLocalMap yang batal akan dikosongkan semasa get(), set(), dan alih keluar () daripada nilai ThreadLocal. Walau bagaimanapun, langkah pencegahan pasif ini tidak dapat menjamin bahawa tiada kebocoran ingatan akan berlaku:
- Menggunakan ThreadLocal statik memanjangkan kitaran hayat ThreadLocal, yang boleh menyebabkan kebocoran memori
- Peruntukan menggunakan ThreadLocal dan tidak lagi memanggil kaedah get(), set(), remove(), yang akan membawa kepada kebocoran memori
Jika anda menggunakan rujukan yang kukuh: Kami tahu bahawa kitaran hayat ThreadLocalMap pada asasnya adalah sama dengan kitaran hayat Thread Jika utas semasa tidak ditamatkan, maka ThreadLocalMap tidak akan dikitar semula oleh GC , dan ThreadLocalMap memegang hak untuk rujukan ThreadLocal Strong, maka ThreadLocal tidak akan dikitar semula Apabila kitaran hayat benang panjang, jika ia tidak dipadamkan secara manual, ia akan menyebabkan pengumpulan kv, mengakibatkan OOM
- Jika anda menggunakan rujukan lemah: lemah Objek dalam rujukan mempunyai tempoh pengisytiharan yang sangat singkat, kerana semasa sistem GC, selagi rujukan lemah ditemui, objek akan dikitar semula tanpa mengira sama ada ruang timbunan berada mencukupi. Apabila rujukan kukuh ThreadLocal dikitar semula, rujukan lemah yang dipegang oleh ThreadLocalMap juga akan dikitar semula Jika kv tidak dipadamkan secara manual, ia akan menyebabkan pengumpulan nilai dan juga membawa kepada OOM
ThreadLocal untuk membersihkannya selepas setiap penggunaan. remove()
Atas ialah kandungan terperinci Bagaimana untuk menggunakan kelas Java ThreadLocal. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas











Java 8 memperkenalkan API Stream, menyediakan cara yang kuat dan ekspresif untuk memproses koleksi data. Walau bagaimanapun, soalan biasa apabila menggunakan aliran adalah: bagaimana untuk memecahkan atau kembali dari operasi foreach? Gelung tradisional membolehkan gangguan awal atau pulangan, tetapi kaedah Foreach Stream tidak menyokong secara langsung kaedah ini. Artikel ini akan menerangkan sebab -sebab dan meneroka kaedah alternatif untuk melaksanakan penamatan pramatang dalam sistem pemprosesan aliran. Bacaan Lanjut: Penambahbaikan API Java Stream Memahami aliran aliran Kaedah Foreach adalah operasi terminal yang melakukan satu operasi pada setiap elemen dalam aliran. Niat reka bentuknya adalah

PHP adalah bahasa skrip yang digunakan secara meluas di sisi pelayan, terutamanya sesuai untuk pembangunan web. 1.PHP boleh membenamkan HTML, memproses permintaan dan respons HTTP, dan menyokong pelbagai pangkalan data. 2.PHP digunakan untuk menjana kandungan web dinamik, data borang proses, pangkalan data akses, dan lain -lain, dengan sokongan komuniti yang kuat dan sumber sumber terbuka. 3. PHP adalah bahasa yang ditafsirkan, dan proses pelaksanaan termasuk analisis leksikal, analisis tatabahasa, penyusunan dan pelaksanaan. 4.Php boleh digabungkan dengan MySQL untuk aplikasi lanjutan seperti sistem pendaftaran pengguna. 5. Apabila debugging php, anda boleh menggunakan fungsi seperti error_reporting () dan var_dump (). 6. Mengoptimumkan kod PHP untuk menggunakan mekanisme caching, mengoptimumkan pertanyaan pangkalan data dan menggunakan fungsi terbina dalam. 7

PHP dan Python masing -masing mempunyai kelebihan sendiri, dan pilihannya harus berdasarkan keperluan projek. 1.Php sesuai untuk pembangunan web, dengan sintaks mudah dan kecekapan pelaksanaan yang tinggi. 2. Python sesuai untuk sains data dan pembelajaran mesin, dengan sintaks ringkas dan perpustakaan yang kaya.

PHP sesuai untuk pembangunan web, terutamanya dalam pembangunan pesat dan memproses kandungan dinamik, tetapi tidak baik pada sains data dan aplikasi peringkat perusahaan. Berbanding dengan Python, PHP mempunyai lebih banyak kelebihan dalam pembangunan web, tetapi tidak sebaik python dalam bidang sains data; Berbanding dengan Java, PHP melakukan lebih buruk dalam aplikasi peringkat perusahaan, tetapi lebih fleksibel dalam pembangunan web; Berbanding dengan JavaScript, PHP lebih ringkas dalam pembangunan back-end, tetapi tidak sebaik JavaScript dalam pembangunan front-end.

PHP dan Python masing -masing mempunyai kelebihan sendiri dan sesuai untuk senario yang berbeza. 1.PHP sesuai untuk pembangunan web dan menyediakan pelayan web terbina dalam dan perpustakaan fungsi yang kaya. 2. Python sesuai untuk sains data dan pembelajaran mesin, dengan sintaks ringkas dan perpustakaan standard yang kuat. Apabila memilih, ia harus diputuskan berdasarkan keperluan projek.

Kapsul adalah angka geometri tiga dimensi, terdiri daripada silinder dan hemisfera di kedua-dua hujungnya. Jumlah kapsul boleh dikira dengan menambahkan isipadu silinder dan jumlah hemisfera di kedua -dua hujungnya. Tutorial ini akan membincangkan cara mengira jumlah kapsul yang diberikan dalam Java menggunakan kaedah yang berbeza. Formula volum kapsul Formula untuk jumlah kapsul adalah seperti berikut: Kelantangan kapsul = isipadu isipadu silinder Dua jumlah hemisfera dalam, R: Radius hemisfera. H: Ketinggian silinder (tidak termasuk hemisfera). Contoh 1 masukkan Jejari = 5 unit Ketinggian = 10 unit Output Jilid = 1570.8 Unit padu menjelaskan Kirakan kelantangan menggunakan formula: Kelantangan = π × r2 × h (4

Phphassignificantelympactedwebdevelopmentandextendsbeyondit.1) itpowersmajorplatformslikeworderpressandexcelsindatabaseIntions.2) php'SadaptabilityAldoStoScaleforlargeapplicationFrameworksLikelara.3)

Sebab mengapa PHP adalah timbunan teknologi pilihan untuk banyak laman web termasuk kemudahan penggunaannya, sokongan komuniti yang kuat, dan penggunaan yang meluas. 1) Mudah dipelajari dan digunakan, sesuai untuk pemula. 2) Mempunyai komuniti pemaju yang besar dan sumber yang kaya. 3) Digunakan secara meluas dalam platform WordPress, Drupal dan lain -lain. 4) Mengintegrasikan dengan ketat dengan pelayan web untuk memudahkan penggunaan pembangunan.
