ה- Java ThreadLocal משמש ליצירת משתנים מקומיים לתהליכים. אנו יודעים שכל התהליכים של אובייקט משתפים את המשתנים שלו, כך שהמשתנה אינו בטוח לתהליכים. אנו יכולים להשתמש בסנכרון עבור בטיחות התהליכים, אך אם רוצים להימנע מסנכרון, נוכל להשתמש במשתנים ThreadLocal. כל תהליך יש לו את המשתנה ThreadLocal המשלו וניתן לוותר על המטופלים ועל השינויים שלו לתהליך. מופעי ThreadLocal נכנסים בדרך כלל כשדות סטטיים פרטיים במחלקות שרוצות לקשר מצב עם תהליך. מופעי ThreadLocal מופיעים בדרך כלל כשדות סטטיים פרטיים במחלקות שרוצות לקשר מצב עם תהליך.
Java ThreadLocal
כל תהליך יש לו את המשתנה הפרטי שלו ThreadLocal והוא יכול להשתמש בשיטות get() ו-set() שלו כדי לקבל את הערך המוגדר כברירת מחדל או לשנות אותו באופן מקומי לתהליך. דוגמאות ThreadLocal מהוות בדרך כלל שדות סטטיים פרטיים במחלקות שרוצות לשייך מצב עם תהליך.
דוגמת Java ThreadLocal
כאן דוגמה קטנה המראה את שימוש ב- ThreadLocal בתוכנית Java ומוכיחה כי כל תהליך מסוגל להשתמש בגרסת המשתנה 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());
}
}
פלט של דוגמא זו של תוכנית Java 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
כפי שניתן לראות מהפלט, ניתן לראות ש-Thread-0 שינתה את ערך ה-formatter, אך ה-formatter של thread-2 נותר זהה לערך שאותחל. תכלית זו ניתן לראות גם בתבנית זו לגבי תהליכים אחרים. עדכון: נוסף ל-ThreadLocal class ב-Java 8 שיטה חדשה בשם withInitial()
, המקבלת את ממשק ה-Supplier כארגומנט. ניתן להשתמש בביטויי למבה כדי ליצור בקלות את המופע של ThreadLocal. לדוגמה, משתנה ה-ThreadLocal של ה-formatter שמוצג למעלה יכול להיות מוגדר בשורה אחת כך:
private static final ThreadLocal<SimpleDateFormat> formatter =
ThreadLocal.<SimpleDateFormat>withInitial
(() -> {return new SimpleDateFormat("yyyyMMdd HHmm");});
אם אתה חדש בתכונות של Java 8, עדיף לבדוק את תכונות של Java 8 ואת ממשקי פונקציות של Java 8. זהו כל הקשור ל-ThreadLocal בתכנות ב-Java. התייחסות: מסמך ה-API
Source:
https://www.digitalocean.com/community/tutorials/java-threadlocal-example