ãã«ãã¹ã¬ãããšããããµããŒãããã©ã€ãã©ãªãæåŠããJavaããã°ã©ããŒã¯ã»ãšãã©ããŸããããåé¡ã詳现ã«èª¿æ»ããæéãèŠã€ãã人ã¯ããã«å°ãªããªããŸãã 代ããã«ãç¹å®ã®ã¿ã¹ã¯ã«å¿
èŠãªã ããããŒã«ã€ããŠåŠç¿ããå¿
èŠãªå Žåã«ã®ã¿ããŒã«ã«æ°ãããã¯ããã¯ãè¿œå ããŸãã ãããã£ãŠãé©åãªã¢ããªã±ãŒã·ã§ã³ãäœæããŠå®è¡ããããšã¯ã§ããŸããããã£ãšããŸãããããšãã§ããŸãã ã³ã³ãã€ã©ãŒãšJavaä»®æ³ãã·ã³ã®æ©èœãç解ãããšãããå¹ççã§çç£çãªã³ãŒããäœæããã®ã«åœ¹ç«ã¡ãŸãã
5ã€ã®äºæ...ã·ãªãŒãºã®ä»åã®èšäºã§ã¯ãåæã¡ãœãããæ®çºæ§å€æ°ãã¢ãããã¯ã¯ã©ã¹ãªã©ããã«ãã¹ã¬ããããã°ã©ãã³ã°ã®åŸ®åŠãªåŽé¢ãããã€ã玹ä»ããŸãã ç¹ã«ããããã®æ§æèŠçŽ ã®äžéšãJVMããã³Javaã³ã³ãã€ã©ãšçžäºäœçšããæ¹æ³ãããã³ããŸããŸãªçžäºäœçšãã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ã«äžãã圱é¿ã«ã€ããŠèª¬æããŸãã
翻蚳è
泚ïŒç§ã¯ãã«ãã¹ã¬ããããã°ã©ãã³ã°ã«é¢ããããã5ã€ã®ããšãç¥ããªãã£ã人ã®1人ã§ããããããã®èšäºã¯ããã§å
¬éãã䟡å€ããããšèããŸãããã翻蚳ã«ééããç¯ãå¯èœæ§ããããããä¿®æ£ãæè¿ããŸãç±æã
翻蚳è
泚2ïŒã³ã¡ã³ãã§ã¯ãç¥èã®ãã人ããããã¯ã«é¢ãããªã³ã¯ãšæ
å ±ãå
±æããŸããèšäºã®å
容ãš
åããããé¢çœãã§ãïŒ
1.åæã¡ãœãããŸãã¯åæãããã¯ïŒ
ã¡ãœããå
šäœãåæåããããä¿è·ããå¿
èŠãããéšåã®ã¿ã宣èšãããã«ã€ããŠæ¢ã«èããŠãããããããŸããã ãã®ãããªç¶æ³ã§ã¯ãJavaã³ã³ãã€ã©ããœãŒã¹ã³ãŒãããã€ãã³ãŒãã«å€æãããšãã«ãåæã¡ãœãããšåæãããã¯ã§éåžžã«ç°ãªãæ¹æ³ã§åäœããããšãç¥ã£ãŠãããšåœ¹ç«ã¡ãŸãã
JVMãåæã¡ãœãããå®è¡ãããšãå®è¡äžã®ã¹ã¬ããã¯ããã®ã¡ãœããã®method_infoã§ACC_SYNCHRONIZEDãã©ã°ãèšå®ãããŠãããšå€æããŸãã 次ã«ããªããžã§ã¯ãã«èªåçã«ããã¯ãèšå®ããã¡ãœãããåŒã³åºããããã¯ã解é€ããŸãã äŸå€ãã¹ããŒããããšãã¹ã¬ããã¯èªåçã«ããã¯ã解é€ããŸãã
äžæ¹ãåæãããã¯ã¯ãJVMã«çµã¿èŸŒãŸãããªããžã§ã¯ãããã¯èŠæ±ãšäŸå€åŠçã®ãµããŒãããã€ãã¹ããããããã€ãã³ãŒãã§æ瀺çã«èšè¿°ããå¿
èŠããããŸãã ãããã¯ã®ãã€ãã³ãŒããèŠããšãã¡ãœãããšæ¯èŒããŠå€ãã®è¿œå æäœããããã¯å
ã«ãããŸãã ãªã¹ã1ã¯äž¡æ¹ã®åŒã³åºãã瀺ããŠããŸãã
ãªã¹ã1.åæãžã®2ã€ã®ã¢ãããŒãã
ããã±ãŒãž com.geekcap ;
ãããªã㯠ã¯ã©ã¹ SynchronizationExample {
private int i ;
public synchronized int synchronizedMethodGet ïŒ ïŒ {
ç§ãè¿ã ;
}
public int synchronizedBlockGet ïŒ ïŒ {
synchronized ïŒ this ïŒ {
ç§ãè¿ã ;
}
}
}
synchronizedMethodGetïŒïŒã¡ãœããã¯ã次ã®ãã€ãã³ãŒããçæããŸãã
0ïŒaload_0
1ïŒgetfield
2ïŒããã
3ïŒiconst_m1
4ïŒåçº
次ã«ãsynchronizedBlockGetïŒïŒã¡ãœããã®ãã€ãã³ãŒãã瀺ããŸãã
0ïŒaload_0
1ïŒéè€
2ïŒastore_1
3ïŒmonitorenter
4ïŒaload_0
5ïŒgetfield
6ïŒnop
7ïŒiconst_m1
8ïŒaload_1
9ïŒmonitorexit
10ïŒã¢ã€ã«ã©ã³ã
11ïŒastore_2
12ïŒaload_1
13ïŒmonitorexit
14ïŒaload_2
15ïŒæãã
åæãããã¯ãäœæãããšã16è¡ã®ãã€ãã³ãŒããè¿ãããŸããããåæã¡ãœããã¯5è¡ã®ã¿ãè¿ããŸããã
2.ãã¹ã¬ããå
ãïŒThreadLocalïŒå€æ°ã
ã¯ã©ã¹ã®ãã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹ã«å¯ŸããŠå€æ°ã®1ã€ã®ã€ã³ã¹ã¿ã³ã¹ãä¿åããå Žåã¯ãéçã¯ã©ã¹å€æ°ã䜿çšããŸãã åã¹ã¬ããã®å€æ°ã®ã€ã³ã¹ã¿ã³ã¹ãä¿åããå Žåã¯ãThreadLocalå€æ°ã䜿çšããŸãã ThreadLocalå€æ°ã¯ãåã¹ã¬ãããç¬èªã«åå¥ã«åæåãããå€æ°ã®ã€ã³ã¹ã¿ã³ã¹ãgetïŒïŒãŸãã¯setïŒïŒã¡ãœãããä»ããŠã¢ã¯ã»ã¹ãããšããç¹ã§ãéåžžã®å€æ°ãšç°ãªããŸãã
ã³ãŒããéãåã¹ã¬ããã®ãã¹ãäžæã«æ±ºå®ããããšãç®æšãšãããã«ãã¹ã¬ããã³ãŒããã¬ãŒãµãéçºããŠãããšããŸãã åé¡ã¯ãè€æ°ã®ã¹ã¬ããã«ããã£ãŠè€æ°ã®ã¯ã©ã¹ã®è€æ°ã®ã¡ãœããã調æŽããå¿
èŠãããããšã§ãã ThreadLocalããªããã°ãããã¯æ±ãã«ããã§ãããã ã¹ã¬ããã®å®è¡ãéå§ããããšããã«ãŒã¿ãŒã«ããèå¥ã®ããã®äžæã®ããŒã«ãŒãçæãããã¬ãŒã¹æã«åã¡ãœããã«ãã®ããŒã«ãŒãæž¡ãå¿
èŠããããŸãã
ThreadLocalã䜿çšãããšãããã¯ç°¡åã§ãã ã¹ã¬ããã¯ãå®è¡ã®éå§æã«ThreadLocalå€æ°ãåæåããŠãããåã¯ã©ã¹ã®åã¡ãœããããã¢ã¯ã»ã¹ããŠãå€æ°ã¯çŸåšå®è¡äžã®ã¹ã¬ããã®ã¿ã®ãã¬ãŒã¹æ
å ±ãä¿åããŸãã ãã®å®äºãå®äºãããšãã¹ã¬ããã¯ãåã
ã®ãã¬ãŒã¹ã¬ã³ãŒããããã¹ãŠã®ã¬ã³ãŒããç¶æããå¶åŸ¡ãªããžã§ã¯ãã«è»¢éã§ããŸãã
ThreadLocalã®äœ¿çšã¯ãåã¹ã¬ããã®å€æ°ã€ã³ã¹ã¿ã³ã¹ãä¿åããå¿
èŠãããå Žåã«æå³ããããŸãã
3.æ®çºæ§å€æ°ã
ç§ã®æšå®ã§ã¯ãJavaéçºè
ã®ååã ããJavaã«volatileããŒã¯ãŒããããããšãç¥ã£ãŠããŸãã ãããã®ãã¡ããã®æå³ãç¥ã£ãŠããã®ã¯çŽ10ïŒ
ã ãã§ãããå¹æçãªäœ¿ãæ¹ãç¥ã£ãŠãã人ã¯ããã«å°ãªãã ã€ãŸããvolatileããŒã¯ãŒãã䜿çšããå€æ°ã®å®çŸ©ã¯ãå€æ°ã®å€ãç°ãªãã¹ã¬ããã«ãã£ãŠå€æŽãããããšãæå³ããŸãã volatileã®æå³ãå®å
šã«ç解ããã«ã¯ããŸããã¹ã¬ãããéåžžã®äžæ®çºæ§å€æ°ã§ã©ã®ããã«åäœããããç解ããå¿
èŠããããŸãã
ããã©ãŒãã³ã¹ãåäžãããããã«ãJavaèšèªä»æ§ã§ã¯ãJREã¯å€æ°ãåç
§ããåã¹ã¬ããã«å€æ°ã®ããŒã«ã«ã³ããŒãä¿åã§ããŸãã ãã£ãã·ã¥ã«äŒŒãå€æ°ã®ãããã®ãã€ã³ã©ã€ã³ãã³ããŒãæ€èšã§ããŸããããã¯ãå€æ°ã®å€ãžã®ã¢ã¯ã»ã¹ãå¿
èŠã«ãªããã³ã«ã¡ã€ã³ã¡ã¢ãªããã§ãã¯ããããšãåé¿ããã®ã«åœ¹ç«ã¡ãŸãã
ãããã次ã®å Žåã«äœãèµ·ãããæ³åããŠã¿ãŠãã ããïŒ2ã€ã®ã¹ã¬ãããéå§ããæåã®ã¹ã¬ããã¯å€æ°Aã5ãšããŠèªã¿åãã2çªç®ã®ã¹ã¬ããã¯10ãšããŠèªã¿åããŸãã Aã®äžæ£ãªå€ããã ããå€æ°AãvolatileãšããŠããŒã¯ãããŠããå Žåãã¹ã¬ããããã®å€ã«ã¢ã¯ã»ã¹ãããšãã¯ãã€ã§ããAã®ã³ããŒãåãåããçŸåšã®å€ãèªã¿åããŸãã
ã¢ããªã±ãŒã·ã§ã³ã®å€æ°ãå€æŽãããªãå Žåãã€ã³ã©ã€ã³ãã£ãã·ã¥ãæå¹ã§ãã ãã以å€ã®å ŽåãvolatileããŒã¯ãŒããäœãããããšãã§ããããç¥ãããšã¯éåžžã«äŸ¿å©ã§ãã
4.æ®çºæ§vsåæã
å€æ°ãvolatileãšããŠå®£èšãããŠããå Žåãè€æ°ã®ã¹ã¬ãããå€æŽããããšãæåŸ
ãããããšãæå³ããŸãã åœç¶ãJREãvolatileå€æ°ã«äœããã®åœ¢ã®åæã課ããšèããã§ãããã è¯ããæªãããJREã¯volatileå€æ°ã«ã¢ã¯ã»ã¹ãããšãã«æé»çã«åæãæäŸããŸããã1ã€ã®éåžžã«å€§ããªæ³šæç¹ããããŸããvolatileå€æ°ã®èªã¿åãã¯åæãããvolatileå€æ°ãžã®æžã蟌ã¿ã¯åæãããŸãããéã¢ãããã¯æäœã¯åæãããŸããã
ã€ãŸãã次ã®ã³ãŒãã¯ã¹ã¬ããã»ãŒãã§ã¯ãããŸããã
myVolatileVar ++;
ãã®ã³ãŒãã¯æ¬¡ã®ããã«ãèšè¿°ã§ããŸãã
int temp = 0 ;
åæïŒ myVolatileVar ïŒ {
temp = myVolatileVar ;
}
temp ++;
åæïŒ myVolatileVar ïŒ {
myVolatileVar = temp ;
}
ã€ãŸããæ®çºæ§å€æ°ãæé»çã«æŽæ°ãããå Žåãã€ãŸãå€ãèªã¿åãããå€æŽãããæ°ããå€ãšããŠå²ãåœãŠãããå Žåãçµæã¯2ã€ã®åææäœéã§éã¹ã¬ããã»ãŒãã«ãªããŸãã åæã䜿çšããããJREãµããŒãã«äŸåããŠæ®çºæ§å€æ°ãèªåçã«åæããããéžæã§ããŸãã æé©ãªã¢ãããŒãã¯ãã±ãŒã¹ã«ãã£ãŠç°ãªããŸããå€æ°ã«å²ãåœãŠãããæ®çºæ§å€ãçŸåšã®å€ã«äŸåããå ŽåïŒããšãã°ãã€ã³ã¯ãªã¡ã³ãæäœäžïŒãæäœãã¹ã¬ããã»ãŒãã«ããå Žåã¯åæã䜿çšããå¿
èŠããããŸãã
5.ã¢ãããã¯ãã£ãŒã«ãã®æŽæ°ã
ã€ã³ã¯ãªã¡ã³ãããã³ãã¯ãªã¡ã³ãæäœãå®è¡ããããªããã£ãåãå¿
èŠãªå Žåãåæãããã¯ãèªåã§èšè¿°ããããããjava.util.concurrent.atomicããã±ãŒãžã®æ°ããã¢ãããã¯ã¯ã©ã¹ããéžæããæ¹ãã¯ããã«åªããŠããŸãã ã¢ãããã¯ã¯ã©ã¹ã¯ãç¹å®ã®æäœïŒããšãã°ãå¢åæäœãšæžåæäœãæŽæ°ãå€ã®è¿œå ïŒãã¹ã¬ããã»ãŒãã§ããããšãä¿èšŒããŸãã ã¢ãããã¯ã¯ã©ã¹ã®ãªã¹ãã«ã¯ãAtomicIntegerãAtomicBooleanãAtomicLongãAtomicIntegerArrayãªã©ãå«ãŸããŸãã
ã¢ãããã¯ã¯ã©ã¹ã䜿çšããéã®ããã°ã©ãã«ãšã£ãŠã®ç¹æã®èª²é¡ã¯ãæäœã®getãsetãããã³get-setãã¡ããªãå«ããã¹ãŠã®ã¯ã©ã¹æäœãã¢ãããã¯ã§ããããšã§ãã ããã¯ãã¢ãããã¯å€æ°ã®å€ãå€æŽããªãèªã¿åãããã³æžã蟌ã¿æäœãåæãããéèŠãªèªã¿åã/æŽæ°/æžã蟌ã¿æäœã ãã§ã¯ãªãããšãæå³ããŸãã åæãããã³ãŒãã®å±éããã詳现ã«å¶åŸ¡ãããå Žåãåé¿çã¯ã¢ãããã¯ãã£ãŒã«ãã¢ããããŒã¿ã䜿çšããããšã§ãã
Atomic Updaterã䜿çšããŸãã
AtomicIntegerFieldUpdaterãAtomicLongFieldUpdaterãAtomicReferenceFieldUpdaterãªã©ã®ã¢ãããã¯ã¢ããããŒã¿ãŒã¯ãæ¬è³ªçã«æ®çºæ§ãã£ãŒã«ãã«é©çšãããã·ã§ã«ã§ãã å
éšã§ã¯ãJavaã¯ã©ã¹ã©ã€ãã©ãªããããã䜿çšããŸãã ã¢ããªã±ãŒã·ã§ã³ã³ãŒãã§ã¯ããŸã䜿çšãããŸãããã圌ãã®å©ããåããŠç掻ã楜ã«ãå§ããªãçç±ã¯ãããŸããã
ãªã¹ã2ã¯ãã¢ãããã¯æŽæ°ã䜿çšããŠã誰ããèªãã§ããæ¬ãå€æŽããã¯ã©ã¹ã®äŸã瀺ããŠããŸãã
ãªã¹ã2. Bookã¯ã©ã¹ã
ããã±ãŒãž com.geeckap.atomicexample ;
ãããªã㯠ã¯ã©ã¹ ããã¯
{
ãã©ã€ããŒã æååå;
å
¬é å³æž ïŒ ïŒ
{
}
å
¬é å³æž ïŒ æåååïŒ
{
ãã ã name = name ;
}
public String getName ïŒ ïŒ
{
ååãè¿ã ;
}
public void setName ïŒ æåååïŒ
{
ãã ã name = name ;
}
}
Bookã¯ã©ã¹ã¯ããã 1ã€ã®ãã£ãŒã«ãnameãæã€POJOïŒãã¬ãŒã³ãªå€ãJavaãªããžã§ã¯ã-ãã¬ãŒã³ãªå€ãJavaãªããžã§ã¯ãïŒã§ãã
ãªã¹ã3. MyObjectã¯ã©ã¹ã
ããã±ãŒãž com.geeckap.atomicexample ;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater ;
/ **
*
* @author shaines
* /
ãããªã㯠ã¯ã©ã¹ MyObject
{
ãã©ã€ããŒã æ®çºæ§ ãã㯠whatImReading ;
private static final AtomicReferenceFieldUpdater < MyObjectãBook > updater =
AtomicReferenceFieldUpdaterã newUpdater ïŒ
ãã€ãªããžã§ã¯ã ã¯ã©ã¹ ã ãã㯠ã ã¯ã©ã¹ ã ãwhatImReadingã ïŒ ;
public Book getWhatImReading ïŒ ïŒ
{
whatImReadingãè¿ããŸãã
}
public void setWhatImReading ïŒ Book whatImReading ïŒ
{
//this.whatImReading = whatImReading;
ã¢ããããŒã¿ãŒã compareAndSet ïŒ ãã ã ãã ãwhatImReading ãwhatImReading ïŒ ;
}
}
ãªã¹ã3ã®MyObjectã¯ã©ã¹ã¯ããæ³åã®ãšããgetã¡ãœãããšsetã¡ãœãããè¡šããŠããŸãããsetã¡ãœããã¯å¥ã®ããšãè¡ããŸãã æå®ãããããã¯ãžã®å
éšãªã³ã¯ãåã«æäŸãã代ããã«ïŒãªã¹ã3ã®ã³ã¡ã³ãåãããã³ãŒãã«ãã£ãŠè¡ãããŸãïŒãAtomicReferenceFieldUpdaterã䜿çšããŸãã
AtomicReferenceFieldUpdater
Javadocã¯ã次ã®ããã«AtomicReferenceFieldUpdaterãå®çŸ©ããŸãã
æå®ãããã¯ã©ã¹ã®æå®ãããvolatileåç
§ãã£ãŒã«ããžã®ã¢ãããã¯æŽæ°ãå¯èœã«ãããªãã¬ã¯ã·ã§ã³ããŒã¹ã®ãŠãŒãã£ãªãã£ã ãã®ã¯ã©ã¹ã¯ãåãããŒãã®è€æ°ã®åç
§ãã£ãŒã«ããç¬ç«ããŠã¢ãããã¯æŽæ°ã®å¯Ÿè±¡ãšãªãã¢ãããã¯ããŒã¿æ§é ã§äœ¿çšããããã«èšèšãããŠããŸãã
ïŒå²ãåœãŠãããã¯ã©ã¹ã®å²ãåœãŠãããæ®çºæ§åç
§ãã£ãŒã«ããžã®ã¢ãããã¯æŽæ°ãå¯èœã«ãããªãã¬ã¯ã·ã§ã³ããŒã¹ã®ãŠãŒãã£ãªãã£ããã®ã¯ã©ã¹ã¯ãåãã¬ã³ãŒãã®è€æ°ã®åç
§ãã£ãŒã«ããã¢ãããã¯æŽæ°ã®ç¬ç«ãããšã³ãã£ãã£ã§ããã¢ãããã¯ããŒã¿æ§é ã§äœ¿çšããããã®ãã®ã§ãïŒ
ãããæ®éã«ç¿»èš³ããæ¹æ³
ãªã¹ã3ã§ã¯ã3ã€ã®ãã©ã¡ãŒã¿ãŒãåãnewUpdaterã¡ãœãããåŒã³åºãããšã§AtomicReferenceFieldUpdaterãäœæãããŸãã
â¢ãã£ãŒã«ããå«ããªããžã§ã¯ãã®ã¯ã©ã¹ïŒãã®å ŽåãMyObjectïŒ
â¢ã¢ãããã¯ã«æŽæ°ããããªããžã§ã¯ãã®ã¯ã©ã¹ïŒãã®å Žåã¯BookïŒ
â¢ã¢ãããã¯ã¢ããããŒãã®ãã£ãŒã«ãå
ããã§éèŠãªã®ã¯ãsetWhatImReadingãã¢ãããã¯æäœãšããŠå®è¡ãããŠããéã«ãgetWhatImReadingã¡ãœãããäœããã®åæãªãã§å®è¡ãããããšã§ãã
ãªã¹ã4ã¯setWhatImReadingïŒïŒã®äœ¿çšæ¹æ³ã瀺ããå€æ°ãæ£ããå€æŽãããŠããããšã蚌æããŸãã
ãªã¹ã4. Atomic Updaterã®ãã¹ãã±ãŒã¹ã
ããã±ãŒãž com.geeckap.atomicexample ;
import org.junit.Assert ;
import org.junit.Before ;
import org.junit.Test ;
ãããªã㯠ã¯ã©ã¹ AtomicExampleTest
{
ãã©ã€ããŒã MyObject obj ;
@Before
public void setUp ïŒ ïŒ
{
obj = new MyObject ïŒ ïŒ ;
objã setWhatImReading ïŒ æ°ãã æ¬ ïŒ ãJava 2 From Scratchã ïŒ ïŒ ;
}
@ãã¹ã
public void testUpdate ïŒ ïŒ
{
objã setWhatImReading ïŒ new Book ïŒ
ãPro Java EE 5ããã©ãŒãã³ã¹ç®¡çãšæé©åã ïŒ ïŒ ;
ã¢ãµãŒãããŸãã assertEquals ïŒ "誀ã£ãããã¯å" ã
ãPro Java EE 5ããã©ãŒãã³ã¹ç®¡çãšæé©åã ã
objã getWhatImReading ïŒ ïŒ ã getName ïŒ ïŒ ïŒ ;
}
}
çµè«ãšããŠã
ãã«ãã¹ã¬ããããã°ã©ãã³ã°ã¯åžžã«ãã¹ãã§ãããJavaãã©ãããã©ãŒã ãé²åãããããäžéšã®ãã«ãã¹ã¬ããããã°ã©ãã³ã°ã¿ã¹ã¯ãç°¡çŽ åãããµããŒããåŸãããŸããã ãã®èšäºã§ã¯ãåæã¡ãœãããšã³ãŒããããã¯ã®éããThreadLocalå€æ°ã䜿çšããããšã®éèŠæ§ãæ®çºæ§ã«å¯Ÿãã誀解ïŒæ®çºæ§ã«äŸåããå±éºæ§ãå«ãïŒåæã䜿çšããå¿
èŠããããŸãïŒãã¢ãããã¯ã¯ã©ã¹ã®è€éãã®ç°¡åãªæŠèŠã ãã£ãšç¥ããã人ã¯ã
ãªã³ã¯ã®ã»ã¯ã·ã§ã³
ïŒèè
ã®ãµã€ãïŒãåç
§ããŠãã ããã