الخيط المحلي في جافا يُستخدم لإنشاء متغيرات محلية للخيط. نحن نعلم أن جميع الخيوط التابعة لكائن ما تشترك في متغيراته، لذلك المتغير غير آمن للخيوط. يمكننا استخدام التزامن لضمان سلامة الخيط ولكن إذا أردنا تجنب التزامن، يمكننا استخدام متغيرات ThreadLocal
.
جافا ThreadLocal
لكل خيط متغير
ThreadLocal
الخاص به ويمكنه استخدام أساليب get() و set() للحصول على القيمة الافتراضية أو تغيير قيمتها محليًا للخيط. يكون تثبيت الـ ThreadLocal عادةً حقولًا ثابتة خاصة في الفئات التي ترغب في ربط الحالة بخيط.
مثال جافا ThreadLocal
إليك مثال صغير يظهر استخدام ThreadLocal في برنامج جافا ويثبت أن لكل خيط نسخة خاصة من المتغير ThreadLocal. ThreadLocalExample.java
package com.journaldev.threads;
import java.text.SimpleDateFormat;
import java.util.Random;
public class ThreadLocalExample implements Runnable{
// SimpleDateFormat ليس آمنًا للخيوط، لذلك قم بتوفير واحد لكل خيط
private static final ThreadLocal formatter = new ThreadLocal(){
@Override
protected SimpleDateFormat initialValue()
{
return new SimpleDateFormat("yyyyMMdd HHmm");
}
};
public static void main(String[] args) throws InterruptedException {
ThreadLocalExample obj = new ThreadLocalExample();
for(int i=0 ; i<10; i++){
Thread t = new Thread(obj, ""+i);
Thread.sleep(new Random().nextInt(1000));
t.start();
}
}
@Override
public void run() {
System.out.println("Thread Name= "+Thread.currentThread().getName()+" default Formatter = "+formatter.get().toPattern());
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
// يتم تغيير نمط المُنَسِّق هنا بواسطة الخيط، ولكن لن ينعكس ذلك على الخيوط الأخرى
formatter.set(new SimpleDateFormat());
System.out.println("Thread Name= "+Thread.currentThread().getName()+" formatter = "+formatter.get().toPattern());
}
}
إخراج برنامج مثال ThreadLocal جافا أعلاه هو:
Thread Name= 0 default Formatter = yyyyMMdd HHmm
Thread Name= 1 default Formatter = yyyyMMdd HHmm
Thread Name= 0 formatter = M/d/yy h:mm a
Thread Name= 2 default Formatter = yyyyMMdd HHmm
Thread Name= 1 formatter = M/d/yy h:mm a
Thread Name= 3 default Formatter = yyyyMMdd HHmm
Thread Name= 4 default Formatter = yyyyMMdd HHmm
Thread Name= 4 formatter = M/d/yy h:mm a
Thread Name= 5 default Formatter = yyyyMMdd HHmm
Thread Name= 2 formatter = M/d/yy h:mm a
Thread Name= 3 formatter = M/d/yy h:mm a
Thread Name= 6 default Formatter = yyyyMMdd HHmm
Thread Name= 5 formatter = M/d/yy h:mm a
Thread Name= 6 formatter = M/d/yy h:mm a
Thread Name= 7 default Formatter = yyyyMMdd HHmm
Thread Name= 8 default Formatter = yyyyMMdd HHmm
Thread Name= 8 formatter = M/d/yy h:mm a
Thread Name= 7 formatter = M/d/yy h:mm a
Thread Name= 9 default Formatter = yyyyMMdd HHmm
Thread Name= 9 formatter = M/d/yy h:mm a
كما يمكنك رؤية من الإخراج أن الخيط-0 قد قام بتغيير قيمة المنسق ولكن لا يزال منسق الافتراضي للخيط-2 هو نفس القيمة المبدئية. يمكنك رؤية نفس النمط للخيوط الأخرى أيضًا. تحديث: تمت إضافة فئة ThreadLocal في جافا 8 بطريقة جديدة تحتوي على طريقة جديدة withInitial()
التي تأخذ واجهة وظيفية Supplier كمدخل. لذا يمكننا استخدام تعبيرات لامبدا لإنشاء مثيل ThreadLocal بسهولة. على سبيل المثال، يمكن تعريف متغير ThreadLocal للمنسق أعلاه في سطر واحد كما يلي:
private static final ThreadLocal<SimpleDateFormat> formatter =
ThreadLocal.<SimpleDateFormat>withInitial
(() -> {return new SimpleDateFormat("yyyyMMdd HHmm");});
إذا كنت جديدًا على ميزات جافا 8، يرجى التحقق من ميزات جافا 8 و الواجهات الوظيفية في جافا 8. هذا كل شيء بخصوص ThreadLocal في برمجة جافا. المرجع: وثائق واجهة التطبيق
Source:
https://www.digitalocean.com/community/tutorials/java-threadlocal-example