මම ThreadLocal විචල්‍යයක් භාවිතා කළ යුත්තේ කවදාද සහ කෙසේද?


886

මම ThreadLocalවිචල්යයක් භාවිතා කළ යුත්තේ කවදාද ?

එය භාවිතා කරන්නේ කෙසේද?


11
ඔබ ThreadLocal භාවිතා කරන්නේ නම්, කිසි විටෙකත් ඒ මත එතීමක් ලියන්න එපා !!! විචල්‍යය භාවිතා කිරීමට කැමති සෑම සංවර්ධකයෙක්ම එය 'ThreadLocal' බව දැන සිටිය යුතුය
දෝෂයක් නොවේ

2
Ob නොටබග් ඔබ පැහැදිලි නම්, ඔබට ඔබේ විචල්‍යය නම් කළ හැකිය, එවිට ඔබ කටයුතු කරන්නේ ත්‍රෙඩ්ලොකල් අගය සමඟ ය, උදා RequestUtils.getCurrentRequestThreadLocal(). මෙය ඉතා අලංකාර යැයි නොකියන නමුත් බොහෝ විට ThreadLocal ඉතා අලංකාර නොවන බව මෙයින් කියැවේ.
සුළි සුළඟ

Answers:


869

නූල්-ආරක්ෂිත නොවන යම් වස්තුවක් ඔබ සතුව ඇති විට (සහ පොදු) භාවිතා කළ හැකි එක් දෙයක් නම්, නමුත් ඔබට එම වස්තුවට ප්‍රවේශය සමමුහුර්ත කිරීමෙන් වැළකී සිටීමට අවශ්‍යය (මම ඔබ දෙස බලමි , සිම්පල් ඩේට් ෆෝමැට් ). ඒ වෙනුවට, එක් එක් නූල් වලට වස්තුව පිළිබඳ තමන්ගේම උදාහරණයක් දෙන්න.

උදාහරණයක් වශයෙන්:

public class Foo
{
    // SimpleDateFormat is not thread-safe, so give one to each thread
    private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
        @Override
        protected SimpleDateFormat initialValue()
        {
            return new SimpleDateFormat("yyyyMMdd HHmm");
        }
    };

    public String formatIt(Date date)
    {
        return formatter.get().format(date);
    }
}

ප්‍රලේඛනය .


162
සමමුහුර්තකරණය හෝ නූල් ලොකල් සඳහා තවත් විකල්පයක් වන්නේ විචල්‍යය දේශීය විචල්‍යයක් බවට පත් කිරීමයි. දේශීය වර්‍ග සෑම විටම නූල් ආරක්ෂිතයි. ඩේට් ෆෝමැට්ස් සෑදීම සඳහා මිල අධික බැවින් ඒවා දේශීය කිරීම නරක පුරුද්දක් යැයි මම සිතමි, නමුත් මෙම මාතෘකාව පිළිබඳ ස්ථිර ප්‍රමිතික මා දැක නැත.
ජූලියන් චාස්ටැං

19
මෙය අනවසරයෙන් ඇතුළුවීම සඳහා ගෙවිය යුතු ඉහළ මිලකි SimpleDateFormat. සමහර විට නූල් ආරක්ෂිත විකල්පයක් භාවිතා කිරීම වඩා හොඳය . ඔබ එකඟ නම් singletons නරකයි පසුව ThreadLocalඊටත් වඩා නරක ය.
ඇලෙක්සැන්ඩර් රයිසොව්

4
Threadthink ThreadLocal ස්ථිතික හා අවසාන ලෙස ප්‍රකාශ කිරීමට කිසියම් හේතුවක් තිබේද, මම අදහස් කළේ කාර්ය සාධනය හෝ යමක්ද?
සචින් ගෝරාඩ්

4
ThreadLocal.get () ක්‍රමය මඟින් එක් එක් නූල් සඳහා ThreadLocal.initialValue () (වරක්) අමතනු ඇත, එයින් අදහස් වන්නේ එක් එක් නූල් සඳහා සරල ඩේට් ෆෝමැට් වස්තුවක් නිර්මාණය වන බවයි. දේශීය විචල්‍යයන් ලෙස සිම්පල් ඩේට් ෆෝමැට් තිබීම වඩා හොඳ නොවේද (අපට කසළ එකතු කිරීමේ ගැටළු සමඟ කටයුතු කිරීමට අවශ්‍ය නැති නිසා)?
sudeepdino008

3
ඔබේ සිම්පල් ඩේට් ෆෝමැට් සඳහා ද්විත්ව වරහන් ආරම්භයක් භාවිතා නොකිරීමට වගබලා ගන්න, මන්ද එය නිර්නාමික පංතියක් නිර්මාණය කරන බැවින් ඔබේ පන්තියේ පැටවුමට කුණු එකතු කිරීමට නොහැකි වනු ඇත. මතක කාන්දු වීම: නව සිම්පල් ඩේට් ෆෝමැට් () return {applyPattern ("yyyyMMdd HHmm") return};
user1944408

428

ThreadLocalලබා දී ඇති දත්ත පිළිබඳ සඳහනක් බැවින් Thread, ThreadLocalයෙදුම් සේවාදායකවල නූල් තටාක භාවිතා කරමින් ඔබට පන්ති පැටවීමේ කාන්දුවීම් සමඟ අවසන් විය හැකිය . ඔබ යම් පිරිසිදු ගැන ඉතා පරෙස්සම් විය යුතුයි ThreadLocalමනුස්සකම ඔබ get()හෝ set()භාවිතයෙන් ThreadLocalගේ remove()ක්රමය.

ඔබ අවසන් වූ පසු ඔබ පිරිසිදු නොකරන්නේ නම්, යොදවා ඇති වෙබ් ඇප් එකක කොටසක් ලෙස පටවන ලද පංති සඳහා එය යොමු කරන ඕනෑම සඳහනක් ස්ථිර ගොඩවල පවතිනු ඇති අතර කිසි විටෙකත් කසළ එකතු නොවනු ඇත. වෙබ්අප් නැවත සේවයේ යෙදවීම / යෙදවීම Threadඔබේ වෙබ්අප් පන්තියට (එස්) එක් එක් යොමු කිරීම පිරිසිදු නොකරනු ඇත, මන්ද එය ඔබේ වෙබ්අප් Threadසතු දෙයක් නොවන බැවිනි. සෑම අනුපිළිවෙලින්ම යෙදවීම පන්තියේ නව අවස්ථාවක් නිර්මාණය කරනු ඇති අතර එය කිසි විටෙකත් කසළ එකතු නොකෙරේ.

දෝෂය නිවැරදි කිරීම වෙනුවට java.lang.OutOfMemoryError: PermGen spaceසමහර ගූග්ලිං වැඩිවීම නිසා ඔබ පසුව මතකයේ ව්‍යතිරේකයන්ගෙන් අවසන් වනු ඇත -XX:MaxPermSize.

ඔබ මෙම ගැටළු වලට මුහුණ දෙන්නේ නම්, එක්ලිප්ස්ගේ මතක විශ්ලේෂකය සහ / හෝ ෆ්‍රෑන්ක් කීවියට්ගේ මාර්ගෝපදේශය සහ පසු විපරම් අනුගමනය කිරීමෙන් මෙම යොමු කිරීම් රඳවා ගන්නේ කුමන නූල් සහ පන්තියද යන්න ඔබට තීරණය කළ හැකිය .

යාවත්කාලීන කිරීම: ඇලෙක්ස් වාසුර්ගේ බ්ලොග් සටහන නැවත සොයා ගැනීම, එය මට ඇති ThreadLocalගැටළු කිහිපයක් සොයා ගැනීමට උපකාරී විය.


11
ඇලෙක්ස් වාසුර් සිය බ්ලොග් අඩවිය ගෙන ගියේය. මතක කාන්දු ලිපියට වත්මන් සබැඳියක් මෙන්න .
කෙන්ස්ටර්

12
ජූලියන් සම්බන්ධ කර ඇති ත්‍රෙඩ් එක මෙතැනට මාරු වී ඇති බව පෙනේ, එය කියවීම වටී…
ඩොනල් ෆෙලෝස්

28
තොරතුරු දැනුවත්ව සිටියද, කිසිම ආකාරයකින් ප්‍රශ්නයට සත්‍ය වශයෙන්ම පිළිතුරු නොදෙන පිළිතුරක් සඳහා මෙය භයානක උඩු යටිකුරු කිරීමකි.
රොබින්

8
දැන් PermGen ජාවා 8 විසින් මරා දමා ඇති අතර, මෙය මෙම පිළිතුර කිසියම් ආකාරයකින් වෙනස් කරයිද?
නපුරු රෙදි සෝදන යන්ත්‍රය

14
Ob රොබින්: මම එකඟ නැහැ. ප්‍රශ්නය වන්නේ ThreadLocal නිවැරදිව භාවිතා කරන්නේ කෙසේද යන්න, ඕනෑම සංකල්පයක් පිළිබඳ පූර්ණ අවබෝධයක් ලබා ගැනීම සඳහා (ThreadLocal මෙහි) එය භාවිතා නොකරන්නේ කෙසේද සහ එය නොසැලකිලිමත් ලෙස භාවිතා කිරීමේ අවදානම තේරුම් ගැනීම ද වැදගත් වන අතර ෆිල්ගේ පිළිතුර එයයි. වෙනත් පිළිතුරුවලින් ආවරණය නොවන ඔහු එම කරුණ ආවරණය කිරීම ගැන මට සතුටුයි. එම සියලු ඡන්ද සුදුසු ය. QA වෙබ් අඩවියක් නොවී SO විසින් සංකල්ප පිළිබඳ අවබෝධය ගොඩනගා ගත යුතු යැයි මම විශ්වාස කරමි.
සෞරබ් පටිල්

168

වත්මන් නූල් හා සම්බන්ධ යම් සන්දර්භයක් පවත්වා ගැනීම සඳහා බොහෝ රාමු ThreadLocals භාවිතා කරයි. නිදසුනක් ලෙස, වර්තමාන ගනුදෙනුව ත්‍රෙඩ්ලොකල් එකක ගබඩා කර ඇති විට, ඔබට එය සෑම ක්‍රම ඇමතුමකින්ම පරාමිතියක් ලෙස යැවීමට අවශ්‍ය නොවේ. වෙබ් යෙදුම් වර්තමාන ඉල්ලීම සහ සැසිය පිළිබඳ තොරතුරු ත්‍රෙඩ්ලොකල් එකක ගබඩා කළ හැකි අතර එමඟින් යෙදුමට පහසුවෙන් ප්‍රවේශ විය හැකිය. එන්නත් කරන ලද වස්තූන් සඳහා අභිරුචි විෂය පථයන් ක්‍රියාත්මක කිරීමේදී Guice සමඟ ඔබට ThreadLocals භාවිතා කළ හැකිය (ගයිස් හි පෙරනිමි සේවාදායක පරාසයන් බොහෝ විට ඒවා භාවිතා කරයි).

ThreadLocals යනු එක් ආකාරයක ගෝලීය විචල්‍යයන්ය (ඒවා එක් නූලකට පමණක් සීමා වී ඇති නිසා තරමක් අඩු නපුරක් වුවද), එබැවින් අනවශ්‍ය අතුරු ආබාධ සහ මතක කාන්දු වීම වළක්වා ගැනීමට ඒවා භාවිතා කිරීමේදී ඔබ ප්‍රවේශම් විය යුතුය. ඔබේ API නිර්මාණය කරන්න එවිට ThreadLocal අගයන් තවදුරටත් අවශ්‍ය නොවන විට ඒවා ස්වයංක්‍රීයව නිෂ්කාශනය වන අතර ඒපීඅයි වැරදි ලෙස භාවිතා කිරීමට නොහැකි වනු ඇත (උදාහරණයක් ලෙස මේ වගේ ). කේතය පිරිසිදු කිරීමට ThreadLocals භාවිතා කළ හැකි අතර සමහර දුර්ලභ අවස්ථාවන්හිදී යමක් වැඩ කිරීමට ඇති එකම ක්‍රමය ඒවාය (මගේ වර්තමාන ව්‍යාපෘතියට එවැනි අවස්ථා දෙකක් තිබුණි; ඒවා මෙහි "ස්ථිතික ක්ෂේත්‍ර සහ ගෝලීය විචල්‍යයන්" යටතේ ලේඛනගත කර ඇත ).


4
එක්ස්පෝජෝ රාමුව (www.expojo.com) විසින් විවරණ සහ එන්නත් කිරීමේ පොදු අවශ්‍යතාවයකින් තොරව ORM සැසිය / පර්සිස්ටෙන්ස් මැනේජර් වෙත ප්‍රවේශ වීමට ඉඩ දෙන්නේ එලෙසිනි. එය 'වස්තු එන්නත් කිරීම' වෙනුවට 'නූල් එන්නත් කිරීම' වැනි ය. එම පරායත්තතාවයන් අවශ්‍ය විය හැකි සෑම වස්තුවකටම ඒවා කාවැද්දීමේ අවශ්‍යතාවයකින් තොරව (සහ ඉහළින්) පරායත්තයන්ට ප්‍රවේශය සපයයි. සම්භාව්‍ය DI වෙනුවට (උදා: වසන්තය ආදිය) නූල් එන්නත් කරන විට ඔබට DI රාමුවක් සාදා ගත හැකි ආකාරය පුදුම සහගතය
Volksman

27
මෙම අත්‍යවශ්‍ය පිළිතුර සොයා ගැනීමට මට මෙතරම් පහළට අනුචලනය කිරීමට සිදු වූයේ ඇයි?
ජෙරමි ස්ටයින්

1
S එස්කෝ, ඔබේ ව්‍යාපෘතියේදී, ඔබ හැෂ් කේතයේ හා සමානව ThreadLocal භාවිතය අනවශ්‍යය. වඩා හොඳ ප්‍රවේශයක් නම්, අවශ්‍ය විටෙක හැෂ් කේතයක් / සමාන ශ්‍රිතයක් වෙත යොමු කිරීමක් නිර්මාණය කිරීම හෝ සම්මත කිරීම ය. මේ ආකාරයෙන්, ඔබට ThreadLocal හැක් කිරීමේ අවශ්‍යතාවය සම්පූර්ණයෙන්ම වළක්වා ගත හැකිය.
පැසීරියර්

1
@ ජෙරමිස්ටයින්, වඩා හොඳ පිළිතුරු වන්නේ stackoverflow.com/a/817911/632951 සහ stackoverflow.com/a/17398338/632951 සහ stackoverflow.com/a/818364/632951
පැකේරියර්

1
TL භාවිතය පිළිබඳ හොඳම පැහැදිලි කිරීම මෙයයි.
ඩෙක්ස්ටර්

52

ජාවා හි, ඔබට එක් නූලකට වෙනස් විය හැකි දත්තයක් තිබේ නම්, ඔබේ තේරීම වන්නේ එම දත්ත අවශ්‍ය සෑම ක්‍රමයකටම (හෝ අවශ්‍ය විය හැකි) සම්මත කිරීම හෝ දත්ත නූල් සමඟ සම්බන්ධ කිරීමයි. ඔබගේ සියලු ක්‍රම දැනටමත් පොදු "සන්දර්භය" විචල්‍යයක් හරහා ගමන් කිරීමට අවශ්‍ය නම් සෑම තැනකම දත්ත සමුදාය ක්‍රියාත්මක කළ හැකිය.

එය එසේ නොවේ නම්, අතිරේක පරාමිතියක් සමඟ ඔබේ ක්‍රමයේ අත්සන අවුල් කිරීමට ඔබට අවශ්‍ය නොවනු ඇත. නූල් රහිත ලෝකයක, ඔබට ජාවා ගෝලීය විචල්‍යයකට සමාන ගැටළුව විසඳා ගත හැකිය. නූල් වචනයකින්, ගෝලීය විචල්‍යයකට සමාන වන්නේ නූල්-දේශීය විචල්‍යයකි.


13
එබැවින් ඔබ ග්ලෝබල් වළක්වා ගන්නා ආකාරයටම නූල් දේශීයයන්ගෙන් වැළකී සිටිය යුතුය. වටිනාම වටිනාකම් පසුකරනවා වෙනුවට ග්ලෝබල් (නූල් දේශීයයන්) නිර්මාණය කිරීම සුදුසු බව මට පිළිගත නොහැකිය, මිනිසුන් කැමති නැත එය නිරාකරණය කිරීමට අවශ්‍ය නොවන ගෘහ නිර්මාණ ගැටලු බොහෝ විට හෙළි කරයි.
ජුවාන් මෙන්ඩිස්

10
සමහර විට ... ඔබට ප්‍රයෝජනවත් විය හැකිය, ඔබට දැනට පවතින විශාල කේත පදනමක් තිබේ නම්, ඔබට සෑම තැනකම සම්මත කළ යුතු නව දත්තයක් එකතු කළ යුතුය , උදා: සැසි සන්දර්භය, ඩීබී ගනුදෙනුව, පුරනය වූ පරිශීලකයා යනාදිය. .
කෝනල් මැසන්

6
දත්ත වෙනුවට ඩේටම් භාවිතා කිරීම සඳහා ප්‍රශංසාව.
ගැඹුරු

මේක මට කුතුහලයක් ඇති කළා. 'datum' is the singular form and 'data' is the plural form.
සිද්ධාර්ථ

25

ජාවා කොන්කුරන්සි ඉන් ප්‍රැක්ටිස් පොතේ ඉතා හොඳ උදාහරණයක් තිබේ . කතෘ (කොහෙද යොෂුවා Bloch ), නූල් සිර නූල් ආරක්ෂාව සාක්ෂාත් කර ගැනීම ඉතා සරළ ක්රම වලින් එකක් වන අතර, ආකාරය විස්තර ThreadLocal නූල් සිර පවත්වාගෙන යාම වඩා විධිමත් ක්රමයක් වන්නේ ප්රචණ්ඩත්වයයි. අවසානයේදී ඔහු එය ගෝලීය විචල්‍යයන් ලෙස භාවිතා කිරීමෙන් මිනිසුන්ට එය අනිසි ලෙස භාවිතා කළ හැකි ආකාරය පැහැදිලි කරයි.

මම සඳහන් කළ පොතෙන් පෙළ පිටපත් කර ඇති නමුත් 3.10 කේතය අස්ථානගත වී ඇති බැවින් ThreadLocal භාවිතා කළ යුත්තේ කොතැනද යන්න තේරුම් ගැනීම එතරම් වැදගත් නොවේ.

විකෘති සිංගල්ටන් හෝ ගෝලීය විචල්‍යයන් මත පදනම් වූ මෝස්තර බෙදාගැනීම වැළැක්වීම සඳහා නූල්-දේශීය විචල්‍යයන් බොහෝ විට භාවිතා කරයි. නිදසුනක් ලෙස, එක් එක් නූල් යෙදුමක් සෑම ක්‍රමයකටම සම්බන්ධතාවයක් නොපැවැත්වීම සඳහා ආරම්භයේදීම ආරම්භ කරන ලද ගෝලීය දත්ත සමුදා සම්බන්ධතාවයක් පවත්වා ගත හැකිය. ජේඩීබීසී සම්බන්ධතා නූල්-ආරක්ෂිත නොවිය හැකි බැවින්, අතිරේක සම්බන්ධීකරණයකින් තොරව ගෝලීය සම්බන්ධතාවයක් භාවිතා කරන බහු තෙරපුම් යෙදුමක් නූල් ආරක්ෂිත නොවේ. ලැයිස්තුගත කිරීමේ 3.10 හි ConnectionHolder හි මෙන්, JDBC සම්බන්ධතාවය ගබඩා කිරීම සඳහා ThreadLocal භාවිතා කිරීමෙන්, සෑම නූලකටම තමන්ගේම සම්බන්ධතාවයක් ඇත.

යෙදුම් රාමු ක්‍රියාත්මක කිරීමේදී ThreadLocal බහුලව භාවිතා වේ. උදාහරණයක් ලෙස, J2EE බහාලුම් ගනුදෙනු සන්දර්භයක් EJB ඇමතුමක කාලසීමාව සඳහා ක්‍රියාත්මක වන නූල් සමඟ සම්බන්ධ කරයි. ගනුදෙනු සන්දර්භය දරණ ස්ථිතික නූල්-දේශීය භාවිතයෙන් මෙය පහසුවෙන් ක්‍රියාත්මක කළ හැකිය: රාමු කේතයට දැනට ක්‍රියාත්මක වන ගනුදෙනුව කුමක්ද යන්න තීරණය කිරීමට අවශ්‍ය වූ විට, එය මෙම ThreadLocal වෙතින් ගනුදෙනු සන්දර්භය ලබා ගනී. මෙය පහසු වන අතර එය ක්‍රියාත්මක කිරීමේ සන්දර්භය පිළිබඳ තොරතුරු සෑම ක්‍රමයකටම යැවීමේ අවශ්‍යතාවය අඩු කරයි, නමුත් මෙම යාන්ත්‍රණය භාවිතා කරන ඕනෑම කේතයක් රාමුවට සම්බන්ධ කරයි.

නූල් සිරගත කිරීමේ දේපල ගෝලීය විචල්‍යයන් භාවිතා කිරීමේ බලපත්‍රයක් ලෙස හෝ “සැඟවුණු” ක්‍රම තර්ක නිර්මාණය කිරීමේ මාධ්‍යයක් ලෙස සැලකීමෙන් ThreadLocal අපයෝජනය කිරීම පහසුය. ගෝලීය විචල්‍යයන් මෙන්, නූල්-දේශීය විචල්‍යයන්ට නැවත භාවිතයෙන් ract ත් විය හැකි අතර පංති අතර සැඟවුණු කප්ලිං හඳුන්වා දිය හැකි අතර එබැවින් ඒවා ප්‍රවේශමෙන් භාවිතා කළ යුතුය.


19

අත්යවශ්යයෙන්ම, වත්මන් නූල් මත යැපීමට ඔබට විචල්යයක වටිනාකමක් අවශ්ය වන විට සහ වෙනත් ආකාරයකින් නූල් වලට අගය ඇමිණීම ඔබට පහසු නොවේ (උදාහරණයක් ලෙස, උප පංති නූල්).

සාමාන්‍ය අවස්ථාවක් නම්, වෙනත් කේතයක් මඟින් ඔබේ කේතය ක්‍රියාත්මක වන නූල් නිර්මාණය කර ඇති අතර, උදා: සර්වට් බහාලුමක්, හෝ ThreadLocal භාවිතා කිරීම වඩාත් අර්ථවත් වන්නේ ඔබේ විචල්‍යය පසුව “එහි තාර්කික ස්ථානයේ” (විචල්‍යයකට වඩා) නූල් උප පංතියක හෝ වෙනත් හැෂ් සිතියමක එල්ලීම).

මගේ වෙබ් අඩවියේ, මට උනන්දුවක් දැක්විය හැකි ThreadLocal භාවිතා කළ යුත්තේ කෙසේද යන්න පිළිබඳ තවත් සාකච්ඡා සහ උදාහරණ ඇත.

ඔබට නූල් අංකයක් අවශ්‍ය වන සමගාමී ඇල්ගොරිතම වල එක් එක් නූලට “නූල් හැඳුනුම්පතක්” ඇමිණිය හැකි ක්‍රමයක් ලෙස සමහර අය ThreadLocal භාවිතා කිරීමට උපදෙස් දෙයි (උදා: හර්ලිහි සහ ෂාවිට් බලන්න). එවැනි අවස්ථාවන්හිදී, ඔබට සැබවින්ම ප්‍රතිලාභයක් ලැබේදැයි පරීක්ෂා කරන්න!


13
  1. ජාවා හි ThreadLocal JDK 1.2 හි හඳුන්වා දී ඇති නමුත් පසුව ThDLocal විචල්‍යය මත වර්ගයේ ආරක්ෂාව හඳුන්වා දීම සඳහා JDK 1.5 හි ජනනය කරන ලදි.

  2. ThreadLocal Thread විෂය පථය සමඟ සම්බන්ධ කළ හැකිය, Thread විසින් ක්‍රියාත්මක කරන සියලුම කේත වලට ThreadLocal විචල්‍යයන් වෙත ප්‍රවේශය ඇත, නමුත් නූල් දෙකකට එකිනෙක දැකිය නොහැක ThreadLocal විචල්‍යය.

  3. සෑම ත්‍රෙඩ් එකකම ත්‍රෙඩ්ලොකල් විචල්‍යයේ සුවිශේෂී පිටපතක් ඇති අතර එය සාමාන්‍යයෙන් හෝ කිසියම් ව්‍යතිරේකයක් හේතුවෙන් නූල් අවසන් වූ පසු හෝ මිය ගිය පසු කසළ එකතු කිරීමට සුදුසුකම් ලබයි. එම ThreadLocal විචල්‍යයට වෙනත් සජීවී යොමු කිරීම් නොමැත.

  4. ජාවා හි ThreadLocal විචල්‍යයන් සාමාන්‍යයෙන් පන්තිවල පෞද්ගලික ස්ථිතික ක්ෂේත්‍ර වන අතර නූල් තුළ එහි තත්වය පවත්වා ගනී.

තව දුරටත් කියවන්න: ජාවා හි ThreadLocal - උදාහරණ වැඩසටහන සහ නිබන්ධනය


11

ප්‍රලේඛනය එය ඉතා හොඳින් පවසයි: "[නූල්-දේශීය විචල්‍යයකට] ප්‍රවේශ වන සෑම නූලකටම (එහි ලබා ගැනීමේ හෝ සැකසීමේ ක්‍රමය හරහා) විචල්‍යයේ ස්වාධීනව ආරම්භ කරන ලද පිටපතක් ඇත".

සෑම නූල් එකකටම යම්කිසි පිටපතක් තිබිය යුතු විට ඔබ එකක් භාවිතා කරයි. පෙරනිමියෙන්, දත්ත නූල් අතර බෙදා ගැනේ.


19
පෙරනිමියෙන්, ස්ථිතික වස්තූන් හෝ නූල් අතර පැහැදිලිවම සම්මත වූ වස්තූන් දෙකම එකම වස්තුවකට යොමු දැක්වීමක් ඇති අතර ඒවා බෙදා ගැනේ. ත්‍රෙඩ් එකක දේශීයව ප්‍රකාශයට පත් කරන ලද වස්තු බෙදා නොගනී (ඒවා නූල් තොගයට දේශීය වේ). එය පැහැදිලි කිරීමට අවශ්‍ය විය.
ඉයන් වර්ලි

AnIanVarley: එය පෙන්වා දීමට ස්තූතියි. ඉතින් අපට MyThread පන්තියේ ප්‍රකාශයට පත් කර භාවිතා කරන විචල්‍යතාවයක් තිබේ නම්, එම අවස්ථාවේ දී අපට ThreadLocal අවශ්‍යද? උදාහරණය: පන්තියේ MyThread නූල් දිගු කරයි {String var1;, int var2; case මෙම අවස්ථාවේ දී var1 සහ var2 ත්‍රෙඩ්ගේම තොගයේ කොටසක් වන අතර එය බෙදා නොගනී, එබැවින් අපට මෙම අවස්ථාවේදී ThreadLocal අවශ්‍යද? මගේ අවබෝධය තුළ මම සම්පූර්ණයෙන්ම වැරදියි, කරුණාකර මඟ පෙන්වන්න.
ජයෂ්

4
සෑම නූලකටම තමන්ගේම දෙයක් පිටපත් කර ගැනීමට අවශ්‍ය නම්, එය හුදෙක් දේශීය ලෙස ප්‍රකාශ කළ නොහැක්කේ ඇයි (එය සැමවිටම නූල් ආරක්ෂිතයි).
sudeepdino008

@ sudeepdino008 ඔබට එම නූල් (වෙබ්අප් රාමු, නූල්පූල් පුස්තකාල) නිර්මාණය කිරීම සැමවිටම පාලනය කළ නොහැක
JMess

10

වෙබ්අප් සේවාදායකය නූල් තටාකයක් තබා ThreadLocalගත හැකි අතර සේවාදායකයාට ප්‍රතිචාර දැක්වීමට පෙර var ඉවත් කළ යුතුය, එබැවින් වත්මන් නූල් ඊළඟ ඉල්ලීම මගින් නැවත භාවිතා කළ හැකිය.


8

Threadlocal විචල්‍යය භාවිතා කළ හැකි අවස්ථා දෙකක් -
1- අපට නූල් සමඟ තත්වය සම්බන්ධ කිරීමේ අවශ්‍යතාවයක් ඇති විට (උදා: පරිශීලක හැඳුනුම්පතක් හෝ ගනුදෙනු හැඳුනුම්පතක්). එය සාමාන්‍යයෙන් සිදුවන්නේ සේවාදායකයකු වෙත යන සෑම ඉල්ලීමකටම අද්විතීය ගනුදෙනු ID එකක් ඇති වෙබ් යෙදුමක් සමඟ ය.

// This class will provide a thread local variable which
// will provide a unique ID for each thread
class ThreadId {
    // Atomic integer containing the next thread ID to be assigned
    private static final AtomicInteger nextId = new AtomicInteger(0);

    // Thread local variable containing each thread's ID
    private static final ThreadLocal<Integer> threadId =
        ThreadLocal.<Integer>withInitial(()-> {return nextId.getAndIncrement();});

    // Returns the current thread's unique ID, assigning it if necessary
    public static int get() {
        return threadId.get();
    }
}

මෙහි දී ඉනිටීයල් සමඟ ක්‍රමය ලැම්බඩා ප්‍රකාශනය භාවිතයෙන් ක්‍රියාත්මක වන බව සලකන්න.
2- තවත් භාවිත අවස්ථාවක් වන්නේ අපට නූල් ආරක්ෂිත අවස්ථාවක් ලබා ගැනීමට අවශ්‍ය වූ විට සහ සමමුහුර්තකරණය සමඟ කාර්ය සාධන පිරිවැය වැඩි බැවින් සමමුහුර්තකරණය භාවිතා කිරීමට අපට අවශ්‍ය නැත. එවැනි එක් අවස්ථාවක් වන්නේ සිම්පල් ඩේට් ෆෝමැට් භාවිතා කරන විටය. සිම්පල් ඩේට් ෆෝමැට් නූල් ආරක්ෂිත නොවන බැවින් එය නූල් ආරක්ෂිත කිරීමට යාන්ත්‍රණයක් සැපයිය යුතුය.

public class ThreadLocalDemo1 implements Runnable {
    // threadlocal variable is created
    private static final ThreadLocal<SimpleDateFormat> dateFormat = new ThreadLocal<SimpleDateFormat>(){
        @Override
        protected SimpleDateFormat initialValue(){
            System.out.println("Initializing SimpleDateFormat for - " + Thread.currentThread().getName() );
            return new SimpleDateFormat("dd/MM/yyyy");
        }
    };

    public static void main(String[] args) {
        ThreadLocalDemo1 td = new ThreadLocalDemo1();
        // Two threads are created
        Thread t1 = new Thread(td, "Thread-1");
        Thread t2 = new Thread(td, "Thread-2");
        t1.start();
        t2.start();
    }

    @Override
    public void run() {
        System.out.println("Thread run execution started for " + Thread.currentThread().getName());
        System.out.println("Date formatter pattern is  " + dateFormat.get().toPattern());
        System.out.println("Formatted date is " + dateFormat.get().format(new Date()));
    } 

}

අද්විතීය හැඳුනුම්පත ජනනය කිරීම සඳහා ThreadLocal භාවිතා කිරීමේ වාසිය මම තවමත් දැක නැත, උදාහරණයක් ලෙස ඔබේ සියලු අරමුණු වන්නේ වර්ධක අද්විතීය පූර්ණ සංඛ්‍යාවක් ලබා දීමයි. `` `පොදු පංතියේ ThreadId {// පුද්ගලික ස්ථිතික අවසාන පරමාණුක ඉන්ටෙගර් වෙත පැවරිය යුතු ඊළඟ නූල් හැඳුනුම්පත අඩංගු පරමාණුක පූර්ණ සංඛ්‍යාව nextId = නව පරමාණුක ඉන්ටෙගර් (0); // වත්මන් නූල් වල අද්විතීය හැඳුනුම්පත ලබා දෙයි, අවශ්‍ය නම් එය ලබා දෙයි පොදු ස්ථිතික int get () next nextId..getAndIncrement (); }} `` `
dashenswen

7

ජාවා 8 නිකුතුවේ සිට, ආරම්භ කිරීමට තවත් ප්‍රකාශන ක්‍රමයක් තිබේ ThreadLocal:

ThreadLocal<Cipher> local = ThreadLocal.withInitial(() -> "init value");

ජාවා 8 නිකුතුව තෙක් ඔබට පහත සඳහන් දේ කිරීමට සිදු විය:

ThreadLocal<String> local = new ThreadLocal<String>(){
    @Override
    protected String initialValue() {
        return "init value";
    }
};

තවද, භාවිතා කරන පන්තියේ ක්ෂණික ක්‍රමය (ඉදිකිරීම්කරු, කර්මාන්තශාලා ක්‍රමය) ThreadLocalකිසිදු පරාමිතියක් නොගන්නේ නම්, ඔබට සරලවම ක්‍රම යොමු භාවිතා කළ හැකිය (ජාවා 8 හි හඳුන්වා දී ඇත):

class NotThreadSafe {
    // no parameters
    public NotThreadSafe(){}
}

ThreadLocal<NotThreadSafe> container = ThreadLocal.withInitial(NotThreadSafe::new);

සටහන: ඔබ java.util.function.Supplierලැම්බඩා පසුකර යන බැවින් ඇගයීම කම්මැලි වන අතර එය ඇගයීමට ලක් කරනු ThreadLocal#getලබන්නේ කැඳවූ විට පමණක් වන නමුත් වටිනාකම කලින් තක්සේරු කර නොමැත.


5

ThreadLocal රටාව සමඟ ඔබ ඉතා ප්‍රවේශම් විය යුතුය. ෆිල් වැනි ප්‍රධාන පහළ පැති කිහිපයක් ඇත, නමුත් සඳහන් නොකළ එකක් නම්, ත්‍රෙඩ්ලොකල් සන්දර්භය සැකසෙන කේතය “නැවත ඇතුල් නොවන” බවට වග බලා ගැනීමයි.

තොරතුරු සකසන කේතය දෙවන හෝ තුන්වන වතාවට ක්‍රියාත්මක වන විට අයහපත් දේ සිදුවිය හැකිය, මන්ද ඔබ බලාපොරොත්තු නොවූ විට ඔබේ ත්‍රෙඩ් එකේ තොරතුරු විකෘති වීමට පටන් ගත හැකිය. එබැවින් ඔබ නැවත සැකසීමට පෙර ThreadLocal තොරතුරු සකසා නොමැති බවට වග බලා ගන්න.


2
කේතය සමඟ කටයුතු කිරීමට සූදානම් නම් නැවත ඇතුළුවීම ගැටලුවක් නොවේ. ඇතුල්වීමේදී, විචල්‍යය දැනටමත් සකසා තිබේද යන්න සටහන් කර ගන්න, පිටවීමේදී එහි පෙර අගය (නැවත තිබේ නම්) යථා තත්වයට පත් කරන්න, නැතහොත් එය ඉවත් කරන්න (එසේ නොවේ නම්).
සුපර් කැට්

1
E ජෙෆ්, මචන්, ඔබ ලියන සෑම කේතයකටම එය සත්‍යයක් මිස ThreadLocalරටාවක් නොවේ . ඔබ එසේ කළහොත් F(){ member=random(); F2(); write(member); }සහ F2 නව අගයක් සහිත සාමාජිකයා අභිබවා ගියහොත් , පැහැදිලිවම write(member)ඔබ random()සංස්කරණය කළ අංකය තවදුරටත් ලියන්නේ නැත . මෙය වචනාර්ථයෙන් සාමාන්‍ය බුද්ධියකි. ඒ හා සමානව, ඔබ එසේ කරන්නේ නම් F(){ F(); }, ඔබගේ අනන්ත පුඩුවට වාසනාව! මෙය සෑම තැනකම සත්‍ය වන අතර එය විශේෂිත නොවේ ThreadLocal.
පැසීරියර්

5

කවදා ද?

වස්තුවක් නූල්-ආරක්ෂිත නොවන විට, පරිමාණයට බාධා කරන සමමුහුර්තකරණය වෙනුවට, සෑම වස්තුවකටම එක් වස්තුවක් ලබා දී එය නූල් විෂය පථය ලෙස තබා ගන්න, එය ThreadLocal වේ. බොහෝ විට භාවිතා කරන නමුත් නූල් ආරක්ෂිත නොවන වස්තු වලින් එකක් වන්නේ දත්ත සමුදා සම්බන්ධතාවය සහ ජේඑම්එස් සම්බන්ධතාවයයි.

කෙසේද ?

එක් උදාහරණයක් නම්, මෙම සම්බන්ධතා වස්තු ThreadLocal විචල්‍යයන්හි තබා ගැනීමෙන් තිරය පිටුපස ගනුදෙනු කළමනාකරණය කිරීම සඳහා වසන්ත රාමුව ThreadLocal දැඩි ලෙස භාවිතා කරයි. ඉහළ මට්ටමක, ගනුදෙනුවක් ආරම්භ කළ විට එය සම්බන්ධතාවය ලබා ගනී (සහ ස්වයංක්‍රීය බැඳීම අක්‍රීය කරයි) සහ එය ThreadLocal හි තබා ගනී. තවදුරටත් db ඇමතුම් වලදී එය db සමඟ සන්නිවේදනය කිරීමට එකම සම්බන්ධතාවයක් භාවිතා කරයි. අවසානයේදී, එය ThreadLocal වෙතින් සම්බන්ධතාවය ගෙන ගනුදෙනුව සිදු කරයි (හෝ පෙරළීම) සම්බන්ධතාවය නිදහස් කරයි.

MDC නඩත්තු කිරීම සඳහා log4j ද ThreadLocal භාවිතා කරයි.


5

ThreadLocal විවිධ නූල් අතර බෙදා නොගත යුතු යම් තත්වයක් ඔබට අවශ්‍ය විට එය ප්‍රයෝජනවත් වේ, නමුත් එය එක් එක් නූල් වලින් එහි මුළු ජීවිත කාලය තුළම ප්‍රවේශ විය යුතුය.

උදාහරණයක් ලෙස, එක් එක් ඉල්ලීම වෙනස් නූලකින් සපයන වෙබ් යෙදුමක් ගැන සිතන්න. සෑම ඉල්ලීමක් සඳහාම ඔබට දත්ත කැබැල්ලක් කිහිප වතාවක් අවශ්‍ය යැයි සිතන්න, එය ගණනය කිරීමට තරමක් මිල අධිකය. කෙසේ වෙතත්, එන සෑම ඉල්ලීමක් සඳහාම එම දත්ත වෙනස් වන්නට ඇත, එයින් අදහස් කරන්නේ ඔබට සරල හැඹිලියක් භාවිතා කළ නොහැකි බවයි. මෙම ගැටළුවට සරල, ඉක්මන් විසඳුමක් වනුයේ මෙම ThreadLocalදත්ත වලට විචල්‍ය රඳවා ගැනීමේ ප්‍රවේශයක් තිබීමයි, එවිට ඔබට එය ගණනය කළ යුත්තේ එක් එක් ඉල්ලීම සඳහා එක් වරක් පමණි. ඇත්ත වශයෙන්ම, මෙම ගැටළුව භාවිතයෙන් තොරව විසඳිය හැකි ThreadLocalනමුත් මම එය නිදර්ශන අරමුණු සඳහා සකස් කළෙමි.

එය ThreadLocalඅත්‍යවශ්‍යයෙන්ම ගෝලීය රාජ්‍යයක ස්වරූපයක් බව මතක තබා ගන්න . එහි ප්‍රති As ලයක් වශයෙන්, එය වෙනත් බොහෝ ඇඟවුම් ඇති අතර එය භාවිතා කළ යුත්තේ අනෙක් සියලුම විසඳුම් සලකා බැලීමෙන් පසුව පමණි.


ඔබ ගෝලීය රාජ්‍යයක් බවට පත් කරන්නේ නම් මිස ThreadLocals ගෝලීය රාජ්‍ය නොවේ. ඒවා ප්‍රායෝගිකව සැමවිටම ප්‍රවේශ විය හැකි තොග සම්පතකි. ඔබේ සියලු ක්‍රම වලදී එම විචල්‍යය සරලව පසු කිරීමෙන් ඔබට නූල් දේශීයව අනුකරණය කළ හැකිය (එය පසුබෑමට ලක්ව ඇත); එය ගෝලීය රාජ්‍යයක් බවට පත් නොකරයි ...
Enerccio

එය ගෝලීය රාජ්‍යයේ ආකාරයකි, අර්ථයෙන් එය කේතයේ ඕනෑම තැනක සිට ප්‍රවේශ විය හැකිය (එකම නූල් සන්දර්භය තුළ). මෙම අගය කියවන්නේ සහ ලියන්නේ කවුරුන්ද යන්න පිළිබඳව තර්ක කිරීමට නොහැකි වීම වැනි සියලු ප්‍රතිවිපාක සමඟ මෙය පැමිණේ. ශ්‍රිත පරාමිතියක් භාවිතා කිරීම පසුගාමී දෙයක් නොවේ, එය පිරිසිදු අතුරුමුහුණත් ප්‍රවර්ධනය කිරීම හොඳ පුරුද්දකි. කෙසේ වෙතත්, ඔබේ කේත පදනමේ මුළු ගැඹුර හරහා පරාමිතියක් පසු කිරීම කේත සුවඳක් බව මම ඔබ සමඟ එකඟ වෙමි. නමුත්, බොහෝ අවස්ථාවන්හිදී ThreadLocal භාවිතය ඔබව මෙහි ගෙන ගිය කේත සුවඳක් බව මම විශ්වාස කරමි, එබැවින් මෙය නැවත සලකා බැලිය යුතු දේ.
ඩිමොස්

එය හුදෙක් වස්තු තත්වයේ කොටසක් විය හැකිය, ගෝලීයව භාවිතා කළ යුතු නැත. ෂුවර්, ඔබට ටිකක් ඉහළින් ලැබෙනු ඇත, නමුත් එක් ThreadLocalවස්තුවකට විවිධ වස්තූන් වෙනස් තත්වයක් තිබිය යුතු නම්, ඔබට වස්තු ක්ෂේත්‍රයක් ලෙස භාවිතා කළ හැකිය ...
Enerccio

ඔයා හරි. ThreadLocalගෝලීය වශයෙන් ප්‍රවේශ විය හැකි අනිසි භාවිතයන් කිහිපයකට මම බොහෝ විට පැකිලී ඇත . ඔබ කී පරිදි, එය තවමත් දෘශ්‍යතාව සීමා කරන පන්ති ක්ෂේත්‍රයක් ලෙස භාවිතා කළ හැකිය.
ඩිමෝස්

4

මෙහි ඇත්ත වශයෙන්ම අළුත් කිසිවක් නැත, නමුත් ThreadLocalවෙබ් යෙදුමක බීන් වලංගුකරණය භාවිතා කිරීමේදී එය ඉතා ප්‍රයෝජනවත් බව මම අද සොයා ගතිමි . වලංගු කිරීමේ පණිවිඩ දේශීයකරණය වී ඇත, නමුත් පෙරනිමියෙන් භාවිතා කරයි Locale.getDefault(). ඔබට Validatorවෙනත් ආකාරයකින් වින්‍යාසගත කළ හැකිය MessageInterpolator, නමුත් Localeඔබ ඇමතූ විට නියම කිරීමට ක්‍රමයක් නොමැත validate. එබැවින් ඔබට ස්ථිතික ThreadLocal<Locale>(හෝ වඩා හොඳ, ඔබට අවශ්‍ය විය හැකි වෙනත් දේ සහිත සාමාන්‍ය බහාලුමක් සාදාගෙන ThreadLocalඔබේ අභිමතය පරිදි එය MessageInterpolatorතෝරා ගත Localeහැකිය. ඊළඟ පියවර වන්නේ ServletFilterසැසි අගයක් භාවිතා කරන ලිපියක් ලිවීම හෝ request.getLocale()පෙදෙසි සහ ගබඩාව තෝරා ගැනීමයි. එය ඔබේ ThreadLocalයොමු දැක්වීමේදී.


4

Ununknown (google) විසින් සඳහන් කළ පරිදි, එහි භාවිතය වන්නේ ගෝලීය විචල්‍යයක් නිර්වචනය කිරීමයි, එහි සඳහන් අගය එක් එක් ත්‍රෙඩ් එකෙහි අද්විතීය විය හැකිය. එහි භාවිතයන් සාමාන්‍යයෙන් වර්තමාන ක්‍රියාත්මක කිරීමේ නූල් සමඟ සම්බන්ධ වී ඇති යම් ආකාරයක සන්දර්භීය තොරතුරු ගබඩා කිරීම අවශ්‍ය වේ.

ජාවා ඊඊ නොදන්නා පන්ති වෙත පරිශීලක අනන්‍යතාවය ලබා දීමට අපි එය ජාවා ඊඊ පරිසරයක භාවිතා කරමු (HttpSession හෝ EJB SessionContext වෙත ප්‍රවේශය නොමැත). ආරක්‍ෂාව පදනම් කරගත් මෙහෙයුම් සඳහා අනන්‍යතාවය භාවිතා කරන කේතය මේ ආකාරයෙන්, සෑම ක්‍රම ඇමතුමකදීම පැහැදිලිවම සම්මත නොකර, ඕනෑම තැනක සිට අනන්‍යතාවයට ප්‍රවේශ විය හැකිය.

බොහෝ ජාවා ඊඊ ඇමතුම් වල ඉල්ලීම් / ප්‍රතිචාර චක්‍රය මෙම භාවිතය පහසු කරයි.


4

සමමුහුර්ත නොවන ක්‍රමයේ බහු නූල් මගින් විකෘති වස්තුවට ප්‍රවේශ වීම ThreadLocal විසින් සහතික කරනු ඇත, එයින් අදහස් වන්නේ විකෘති වස්තුව ක්‍රමවේදය තුළ වෙනස් කළ නොහැකි බවට පත් කිරීමයි.

මෙය සාක්ෂාත් කරගනු ලබන්නේ එක් එක් නූල් සඳහා විකෘති වස්තුවකට නව අවස්ථාවක් ලබා දීමෙන් එය වෙත ප්‍රවේශ වීමට උත්සාහ කරන්න. එබැවින් එය එක් එක් නූල් සඳහා දේශීය පිටපතකි. මෙය දේශීය විචල්‍යයක් ලෙස ප්‍රවේශ විය හැකි ක්‍රමයක නිදර්ශන විචල්‍යයක් බවට පත්කිරීමේ යම්කිසි කඩාවැටීමකි. ඔබ දන්නා ක්‍රමය අනුව දේශීය විචල්‍යය ලබා ගත හැක්කේ නූල් වලට පමණි, එක් වෙනසක් වන්නේ; ක්‍රමවේදය ක්‍රියාත්මක වූ පසු දේශීය විචල්‍යයන් නූල් වෙත නොපවතින අතර, අප විසින් පිරිසිදු කරන තෙක් නූල්ලොකල් සමඟ බෙදාගත හැකි විකෘති වස්තුවක් විවිධ ක්‍රම හරහා ලබා ගත හැකිය.

අර්ථ දැක්වීම අනුව:

ජාවා හි ThreadLocal පන්තිය මඟින් එකම නූල් එකකින් පමණක් කියවිය හැකි හා ලිවිය හැකි විචල්‍යයන් නිර්මාණය කිරීමට ඔබට හැකි වේ. මේ අනුව, නූල් දෙකක් එකම කේතය ක්‍රියාත්මක කළත්, කේතයට ThreadLocal විචල්‍යයක් ගැන සඳහනක් තිබුණත්, නූල් දෙක එකිනෙකට ThreadLocal විචල්‍යයන් දැකිය නොහැක.

Threadජාවා වල ඇති සෑම එකක්ම එහි අඩංගු වේ ThreadLocalMap.
කොහෙද

Key = One ThreadLocal object shared across threads.
value = Mutable object which has to be used synchronously, this will be instantiated for each thread.

ThreadLocal ලබා ගැනීම:

දැන් ThreadLocal සඳහා ආවරණ පංතියක් සාදන්න, එය විකෘති වස්තුව පහත පරිදි රඳවා තබා ගනී (සමඟ හෝ නැතිව) initialValue() ) .
දැන් මෙම එතීමේ යන්ත්‍රය සහ සැකසුම විකෘති වස්තුව වෙනුවට නූල් ස්ථානීය උදාහරණ මත ක්‍රියා කරයි.

Threadlocal හි getter () හි threadlocalmap හි කිසිදු අගයක් සොයාගත නොහැකි නම් Thread; එවිට එය නූල් සම්බන්ධව එහි පුද්ගලික පිටපත ලබා ගැනීම සඳහා ආරම්භක අගය () ඉල්ලා සිටී.

class SimpleDateFormatInstancePerThread {

    private static final ThreadLocal<SimpleDateFormat> dateFormatHolder = new ThreadLocal<SimpleDateFormat>() {

        @Override
        protected SimpleDateFormat initialValue() {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd") {
                UUID id = UUID.randomUUID();
                @Override
                public String toString() {
                    return id.toString();
                };
            };
            System.out.println("Creating SimpleDateFormat instance " + dateFormat +" for Thread : " + Thread.currentThread().getName());
            return dateFormat;
        }
    };

    /*
     * Every time there is a call for DateFormat, ThreadLocal will return calling
     * Thread's copy of SimpleDateFormat
     */
    public static DateFormat getDateFormatter() {
        return dateFormatHolder.get();
    }

    public static void cleanup() {
        dateFormatHolder.remove();
    }
}

දැන් wrapper.getDateFormatter()අමතනු ඇති threadlocal.get()අතර එමඟින් මෙම (ත්‍රෙඩ්ලොකල්) උදාහරණය currentThread.threadLocalMapඅඩංගු වේ . ඔව්, ඊට අනුරූප ත්‍රෙඩ්ලොකල් නිදසුන සඳහා අගය (සිම්පල් ඩේට් ෆෝමැට්) ආපසු ලබා දෙන්නේ නම්, මෙම ත්‍රෙඩ්ලොකල් උදාහරණය සමඟ සිතියම එක් කරන්න, ආරම්භක අගය ().


මෙම විකෘති පංතිය මත හෙරුවිත් නූල් ආරක්ෂාව; එක් එක් නූල් මඟින් තමන්ගේම විකෘති නිදසුනක් සමඟ ක්‍රියා කරන නමුත් එකම ThreadLocal නිදසුන සමඟ ක්‍රියා කරයි. ක්‍රම සියළුම නූල් යතුර ලෙස එකම ThreadLocal උදාහරණය බෙදාගනු ඇත, නමුත් අගය ලෙස වෙනස් SimpleDateFormat උදාහරණය.

https://github.com/skanagavelu/yt.tech/blob/master/src/ThreadLocalTest.java


3

විකෘති සිංගල්ටන් හෝ ගෝලීය විචල්‍යයන් මත පදනම් වූ මෝස්තර බෙදාගැනීම වැළැක්වීම සඳහා නූල්-දේශීය විචල්‍යයන් බොහෝ විට භාවිතා කරයි.

ඔබ සම්බන්ධතා තටාකයක් භාවිතා නොකරන විට එක් එක් නූල් සඳහා වෙනම JDBC සම්බන්ධතාවයක් ඇති කිරීම වැනි අවස්ථා වලදී එය භාවිතා කළ හැකිය.

private static ThreadLocal<Connection> connectionHolder
           = new ThreadLocal<Connection>() {
      public Connection initialValue() {
           return DriverManager.getConnection(DB_URL);
          }
     };

public static Connection getConnection() {
      return connectionHolder.get();
} 

ඔබ getConnection අමතන විට, එය එම ත්‍රෙඩ් එක හා සම්බන්ධිත සම්බන්ධතාවයක් ලබා දෙනු ඇත. ඔබට නූල් අතර බෙදා ගැනීමට අවශ්‍ය නොවන දිනය හැඩතල, ගනුදෙනු සන්දර්භය වැනි වෙනත් ගුණාංග සමඟද මෙය කළ හැකිය.

ඔබට ඒ සඳහා දේශීය විචල්‍යයන් ද භාවිතා කළ හැකි නමුත් මෙම සම්පත් සාමාන්‍යයෙන් නිර්මාණයේ කාලය ගත කරයි, එබැවින් ඔබ ඔවුන් සමඟ යම් ව්‍යාපාර තර්කනයක් සිදු කරන සෑම විටම ඒවා නැවත නැවතත් නිර්මාණය කිරීමට ඔබට අවශ්‍ය නැත. කෙසේ වෙතත්, ThreadLocal අගයන් නූල් වස්තුව තුළම ගබඩා කර ඇති අතර නූල් කසළ එකතු කළ විගසම මෙම අගයන් ද නැති වී යයි.

මෙම සබැඳිය ThreadLocal භාවිතය ඉතා හොඳින් පැහැදිලි කරයි.


2
මෙම උදාහරණයේ දී ප්‍රධාන ගැටළුවක් වේ: සම්බන්ධතාවය වසා දැමීමට වගකිව යුත්තේ කවුරුන් ද? ආරම්භක අගය ලෙස මෙම සම්බන්ධතාවය නිර්මාණය කරනවා වෙනුවට, සම්බන්ධතාවයේ පාරිභෝගිකයාට සම්බන්ධතාවය පැහැදිලිව නිර්මාණය කර ThreadLocal හරහා නූල් එකට බැඳීමට ඉඩ දෙන්න. සම්බන්ධතාවයේ නිර්මාතෘ ද වසා දැමීම සඳහා වගකිව යුතුය. මෙම උදාහරණයේ මෙය පැහැදිලි නැත. Transaction.begin () සහ Transaction.end () වැනි දෙයක් මඟින් සම්බන්ධතාවය නිර්මාණය කිරීම හා බැඳීම සරල රාමුවක් තුළ සැඟවිය හැක.
රික්-රේනර් ලුඩ්විග්

3

භාවිතා කිරීම සඳහා 3 ඒවායින් කවරක්ද ඇත පන්ති සහකාරියක් එක් භාවිතය වන හොඳම multithread කේතය, දී SimpleDateFormat වැනි ThreadLocal

සිදුවීම්

1- යෙදුම මන්දගාමී වන අගුළු හෝ සමමුහුර්ත කිරීමේ යාන්ත්‍රණයේ ආධාරයෙන් සමාන කොටස් වස්තුවක් භාවිතා කිරීම

2- ලෙස භාවිතා කරමින් දේශීය වස්තුව ක්රමයක් තුල

මෙම තත්වය තුළ, අපට නූල් 4 ක් තිබේ නම්, එක් එක් ක්‍රමයට 1000 වතාවක් අමතන්න, එවිට අපට
4000 සිම්පල් ඩේට් ෆෝමැට් වස්තුවක් නිර්මාණය කර ඇති අතර ඒවා මකා දැමීමට ජී.සී.

3- ThreadLocal භාවිතා කිරීම

අපි 4 නූල් ඇති වුවහොත් අපි දුන් එක් SimpleDateFormat උදාහරණයක් එක් එක් නූල්
අපට එසේ 4 නූල් , 4 වස්තූන් SimpleDateFormat ය.

අගුළු යාන්ත්‍රණය සහ වස්තු නිර්මාණය හා විනාශ කිරීම අවශ්‍ය නොවේ. (හොඳ කාල සංකීර්ණත්වය සහ අවකාශයේ සංකීර්ණතාව)


2

මෙම ThreadLocalජාවා පන්තිය මඟින් එකම නූල් පමණක් කියවිය හැකි හා ලිවිය හැකි විචල්‍යයන් නිර්මාණය කිරීමට ඔබට හැකි වේ. මේ අනුව, නූල් දෙකක් එකම කේතය ක්‍රියාත්මක කළත්, කේතයට ThreadLocal විචල්‍යයක් ගැන සඳහනක් තිබුණත්, නූල් දෙක එකිනෙකට ThreadLocal විචල්‍යයන් දැකිය නොහැක.

වැඩිදුර කියවන්න


2

[යොමුව සඳහා] හවුල් වස්තුවක යාවත්කාලීන ගැටළු විසඳීමට ThreadLocal හට නොහැක. එකම ත්‍රෙඩ් එකේ ඇති සියලුම මෙහෙයුම් මගින් බෙදා ගන්නා ස්ථිතික ත්‍රෙඩ්ලොකල් වස්තුවක් භාවිතා කිරීම රෙකමදාරු කරනු ලැබේ. [අනිවාර්ය] ඉවත් කිරීමේ () ක්‍රමය ThreadLocal විචල්‍යයන් විසින් ක්‍රියාත්මක කළ යුතුය, විශේෂයෙන් නූල් බොහෝ විට නැවත භාවිතා කරන නූල් තටාක භාවිතා කරන විට. එසේ නොමැති නම්, එය පසුකාලීන ව්‍යාපාරික තර්කනයට බලපාන අතර මතක කාන්දු වීම වැනි අනපේක්ෂිත ගැටළු ඇති කළ හැකිය.


1

හැඹිලිය, යම් වේලාවක ඔබට එකම අගය ගණනය කිරීමට සිදු වන අතර එමඟින් අවසාන යෙදවුම් කට්ටලයක් ක්‍රමයකට ගබඩා කිරීමෙන් සහ ප්‍රති result ලය මඟින් ඔබට කේතය වේගවත් කළ හැකිය. Thread Local Storage භාවිතා කිරීමෙන් ඔබ අගුළු දැමීම ගැන සිතීමෙන් වළකින්න.


1

ThreadLocal යනු නූල් සඳහා පමණක් හුදකලා ගබඩා ඉඩක් ලබා දීම සඳහා JVM විසින් විශේෂයෙන් සපයන ලද ක්‍රියාකාරීත්වයකි. නිදසුනක් ලෙස විෂය පථයේ විචල්‍යය පන්තියේ එක් අවස්ථාවකට පමණක් බැඳී ඇත. සෑම වස්තුවකටම එහි එකම අගයන් ඇති අතර ඒවාට එකිනෙකාගේ අගය නොපෙනේ. ThreadLocal විචල්‍යයන් පිළිබඳ සංකල්පය ද එසේමය, ඒවා නූල් වලට දේශීය වේ වස්තු අවස්ථා අර්ථයෙන් එය නිර්මාණය කළ එක හැර වෙනත් නූල්, එය නොපෙනේ. මෙහි බලන්න

import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;


public class ThreadId {
private static final AtomicInteger nextId = new AtomicInteger(1000);

// Thread local variable containing each thread's ID
private static final ThreadLocal<Integer> threadId = ThreadLocal.withInitial(() -> nextId.getAndIncrement());


// Returns the current thread's unique ID, assigning it if necessary
public static int get() {
    return threadId.get();
}

public static void main(String[] args) {

    new Thread(() -> IntStream.range(1, 3).forEach(i -> {
        System.out.println(Thread.currentThread().getName() + " >> " + new ThreadId().get());
    })).start();

    new Thread(() -> IntStream.range(1, 3).forEach(i -> {
        System.out.println(Thread.currentThread().getName() + " >> " + new ThreadId().get());
    })).start();

    new Thread(() -> IntStream.range(1, 3).forEach(i -> {
        System.out.println(Thread.currentThread().getName() + " >> " + new ThreadId().get());
    })).start();

}
}

1

Threadlocal විසින් ශුන්‍ය පිරිවැය සමඟ වස්තූන් නැවත භාවිතා කිරීමේ හැකියාව ලබා ගැනීම සඳහා ඉතා පහසු ක්‍රමයක් සපයයි.

සෑම යාවත්කාලීන දැනුම්දීමකදීම විකෘති හැඹිලියේ රූපයක් බහු නූල් නිර්මාණය කරන තත්වයක් මට තිබුණි.

මම සෑම ත්‍රෙඩ් එකකම ත්‍රෙඩ්ලොකල් එකක් භාවිතා කළ අතර, පසුව සෑම නූල් එකකටම පැරණි රූපය නැවත සැකසීමට අවශ්‍ය වන අතර පසුව සෑම යාවත්කාලීන දැනුම්දීමකම හැඹිලියෙන් එය යාවත්කාලීන කරන්න.

වස්තු තටාක වලින් නැවත නැවත භාවිතා කළ හැකි වස්තූන් ඒවාට නූල් ආරක්ෂණ පිරිවැය සම්බන්ධ කර ඇති අතර මෙම ප්‍රවේශයට කිසිවක් නොමැත.


1

ThreadLocal විචල්‍යය පිළිබඳ හැඟීමක් ලබා ගැනීමට මෙම කුඩා උදාහරණය උත්සාහ කරන්න:

public class Book implements Runnable {
    private static final ThreadLocal<List<String>> WORDS = ThreadLocal.withInitial(ArrayList::new);

    private final String bookName; // It is also the thread's name
    private final List<String> words;


    public Book(String bookName, List<String> words) {
        this.bookName = bookName;
        this.words = Collections.unmodifiableList(words);
    }

    public void run() {
        WORDS.get().addAll(words);
        System.out.printf("Result %s: '%s'.%n", bookName, String.join(", ", WORDS.get()));
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(new Book("BookA", Arrays.asList("wordA1", "wordA2", "wordA3")));
        Thread t2 = new Thread(new Book("BookB", Arrays.asList("wordB1", "wordB2")));
        t1.start();
        t2.start();
    }
}


නූල් බුක්ඒ පළමුව සිදු කරන්නේ නම් කොන්සෝලය ප්‍රතිදානය:
ප්‍රති ult ල බුක්ඒ: 'වර්ඩ්ඒ 1, වර්ඩ්ඒ 2, වර්ඩ්ඒ 3'.
ප්‍රති Book ලය BookB: 'wordB1, wordB2'.

නූල් BookB පළමුව සිදු කරන්නේ නම් කොන්සෝලය ප්‍රතිදානය:
ප්‍රති ult ලය BookB: 'wordB1, wordB2'.
ප්‍රති Book ල පොත: 'wordA1, wordA2, wordA3'.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.