static final ThreadLocal चर धागे सुरक्षित हैं।
staticकेवल संबंधित थ्रेड के लिए कई वर्गों में थ्रेडलोकल वैरिएबल उपलब्ध कराता है। यह कई वर्गों में संबंधित थ्रेड लोकल वैरिएबल का एक प्रकार का ग्लोबल वैरिएबल डिमार्केशन है।
हम निम्नलिखित कोड नमूने के साथ इस थ्रेड सुरक्षा की जांच कर सकते हैं।
CurrentUser - थ्रेडलोक में वर्तमान यूजर आईडी को स्टोर करता है
TestService- विधि के साथ सरल सेवा - getUser()करेंटयूसर से वर्तमान उपयोगकर्ता को लाने के लिए।
TestThread - यह क्लास कई थ्रेड बनाने के लिए उपयोग की जाती है और उपयोगकर्ता समवर्ती सेट करती है
।
public class CurrentUser
public class CurrentUser {
private static final ThreadLocal<String> CURRENT = new ThreadLocal<String>();
public static ThreadLocal<String> getCurrent() {
return CURRENT;
}
public static void setCurrent(String user) {
CURRENT.set(user);
}
}
public class TestService {
public String getUser() {
return CurrentUser.getCurrent().get();
}
}
।
import java.util.ArrayList;
import java.util.List;
public class TestThread {
public static void main(String[] args) {
List<Integer> integerList = new ArrayList<>();
//creates a List of 100 integers
for (int i = 0; i < 100; i++) {
integerList.add(i);
}
//parallel stream to test concurrent thread execution
integerList.parallelStream().forEach(intValue -> {
//All concurrent thread will set the user as "intValue"
CurrentUser.setCurrent("" + intValue);
//Thread creates a sample instance for TestService class
TestService testService = new TestService();
//Print the respective thread name along with "intValue" value and current user.
System.out.println("Start-"+Thread.currentThread().getName()+"->"+intValue + "->" + testService.getUser());
try {
//all concurrent thread will wait for 3 seconds
Thread.sleep(3000l);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Print the respective thread name along with "intValue" value and current user.
System.out.println("End-"+Thread.currentThread().getName()+"->"+intValue + "->" + testService.getUser());
});
}
}
।
TestThread मुख्य वर्ग चलाएं। आउटपुट -
Start-main->62->62
Start-ForkJoinPool.commonPool-worker-2->31->31
Start-ForkJoinPool.commonPool-worker-3->81->81
Start-ForkJoinPool.commonPool-worker-1->87->87
End-main->62->62
End-ForkJoinPool.commonPool-worker-1->87->87
End-ForkJoinPool.commonPool-worker-2->31->31
End-ForkJoinPool.commonPool-worker-3->81->81
Start-ForkJoinPool.commonPool-worker-2->32->32
Start-ForkJoinPool.commonPool-worker-3->82->82
Start-ForkJoinPool.commonPool-worker-1->88->88
Start-main->63->63
End-ForkJoinPool.commonPool-worker-1->88->88
End-main->63->63
...
विश्लेषण सारांश
- "मुख्य" धागा "62" के रूप में वर्तमान उपयोगकर्ता को शुरू और सेट करता है, समानांतर रूप से "ForkJoinPool.commonPool-कार्यकर्ता -2" धागा शुरू होता है और वर्तमान उपयोगकर्ता को "31" के रूप में सेट करता है, समान रूप से "ForkJoinPool.commonPool-कार्यकर्ता-3" धागा शुरू होता है और वर्तमान सेट करता है उपयोगकर्ता "81" के रूप में, समान रूप से "ForkJoinPool.commonPool-worker-1" थ्रेड शुरू होता है और वर्तमान उपयोगकर्ता को "87" स्टार्ट-मेन-> 62-> 62 स्टार्ट-फॉर जॉइंटपूल.कॉमmonPool-कार्यकर्ता-2-> 31-> 31 के रूप में सेट करता है Start-ForkJoinPool.commonPool-worker-3-> 81-> 81 Start-ForkJoinPool.commonPool-कार्यकर्ता-1-> 87-> 87
- उपरोक्त सभी धागे 3 सेकंड तक सोएंगे
mainनिष्पादन समाप्त होता है और वर्तमान उपयोगकर्ता को "62" के रूप में प्रिंट करता है, समानांतर ForkJoinPool.commonPool-worker-1निष्पादन समाप्त होता है और वर्तमान उपयोगकर्ता को "87" के रूप में प्रिंट करता है, समानांतर ForkJoinPool.commonPool-worker-2निष्पादन समाप्त होता है और वर्तमान उपयोगकर्ता को "31" के रूप में प्रिंट करता है, समानांतर ForkJoinPool.commonPool-worker-3निष्पादन समाप्त होता है और वर्तमान उपयोगकर्ता को "81" के रूप में प्रिंट करता है।
अनुमान
समवर्ती थ्रेड्स सही उपयोगकर्ता प्राप्त करने में सक्षम हैं, भले ही इसे "स्थिर अंतिम थ्रेडलोकल" घोषित किया गया हो