åºç«
ãããã£ãŠãJava ã«ã¯ã¹ã¬ãããããããšãããããŸããããã«ã€ããŠã¯ããBetter together: Java and the Thread classããšããã¿ã€ãã«ã®ã¬ãã¥ãŒã§èªãããšãã§ããŸããããŒã I â å®è¡ã®ã¹ã¬ãããã¹ã¬ããã¯äžŠè¡ããŠäœæ¥ãå®è¡ããããã«å¿ èŠã§ããããã«ãããã¹ã¬ãããäœããã®åœ¢ã§çžäºäœçšããå¯èœæ§ãé«ããªããŸãããããã©ã®ããã«èµ·ããã®ãããããŠã©ã®ãããªåºæ¬çãªããŒã«ãããã®ãââãèŠãŠã¿ãŸããããåç
Thread.yield()ã¯äžå¯è§£ã§ãããã»ãšãã©äœ¿çšãããŸãããã€ã³ã¿ãŒãããäžã§ã¯ããŸããŸãªæ¹æ³ã§èª¬æãããŠããŸããã¹ã¬ããã®åªå é äœã«åºã¥ããŠã¹ã¬ãããéé ããããã¹ã¬ããã®ãã¥ãŒãååšãããšæžããŠãã人ãããŸããä»ã®äººã¯ãã¹ã¬ããã®ã¹ããŒã¿ã¹ããå®è¡äžããããå®è¡å¯èœãã«å€æŽããããšæžããŠããŸã (ãããã®ã¹ããŒã¿ã¹ã«ã¯åºå¥ããªãã«ãããããããã€ãŸã Java ã¯ã¹ããŒã¿ã¹ãåºå¥ããŸãã)ãå®éã®ãšãããããã¯ããŸãç¥ãããŠããŸããããããæå³ã§ã¯ãã£ãšåçŽã§ãã ãã° ( JDK-6416721: (ä»æ§ã¹ã¬ãã) Fix Thread.yield() javadoc ) ãyield()
ã¡ãœããã®ããã¥ã¡ã³ãã«èšé²ãããŠããŸããèªãã§ã¿ããšäžç®çç¶ã§ãããyield()
ãã®ã¡ãœããã¯å®éã«ã¯ããã®ã¹ã¬ããã®å®è¡æéãççž®ã§ãããšããæšå¥šäºé
ã Java ã¹ã¬ãã ã¹ã±ãžã¥ãŒã©ã«æäŸããã ãã§ããããããå®éã«äœãèµ·ããããã€ãŸãã¹ã±ãžã¥ãŒã©ãæšå¥šã«åºã¥ããŠåäœãããã©ããããŸãã¹ã±ãžã¥ãŒã©ãäžè¬çã«äœãè¡ããã¯ãJVM ã®å®è£
ãšãªãã¬ãŒãã£ã³ã° ã·ã¹ãã ã«ãã£ãŠç°ãªããŸãããŸããä»ã®èŠå ã«ãäŸåããå¯èœæ§ããããŸãããã¹ãŠã®æ··ä¹±ã¯ãJava èšèªã®çºå±ã«äŒŽã£ãŠãã«ãã¹ã¬ãããèŠçŽãããããšãåå ã§ããå¯èœæ§ãæãé«ããªããŸããæŠèŠã®è©³çŽ°ã«ã€ããŠã¯ããJava Thread.yield() ã®æŠèŠããåç
§ããŠãã ããã
å¯ã
ã¹ã¬ããã¯å®è¡äžã«ã¹ãªãŒãç¶æ ã«ãªãããšããããŸããããã¯ãä»ã®ã¹ã¬ãããšã®å¯Ÿè©±ã®æãç°¡åãªã¿ã€ãã§ããJava ã³ãŒããå®è¡ãã Java ä»®æ³ãã·ã³ãå®è¡ãããªãã¬ãŒãã£ã³ã° ã·ã¹ãã ã«ã¯ãç¬èªã®ã¹ã¬ããã¹ã±ãžã¥ãŒã©ããããŸããã©ã®ã¹ã¬ããããã€éå§ãããã決å®ããŸããããã°ã©ãã¯ãJava ã³ãŒããããã®ã¹ã±ãžã¥ãŒã©ãçŽæ¥æäœããããšã¯ã§ãããJVM ãä»ããŠã®ã¿æäœã§ããŸãããŠãŒã¶ãŒã¯ãã¹ã±ãžã¥ãŒã©ã«ã¹ã¬ããããã°ããäžæåæ¢ãããã€ãŸãã¹ã¬ãããã¹ãªãŒããããããã«èŠæ±ã§ããŸãã詳现ã«ã€ããŠã¯ãThread.sleep()ããã³How Multithreading worksã®èšäºãåç §ããŠãã ãããWindows ãªãã¬ãŒãã£ã³ã° ã·ã¹ãã ã§ã¹ã¬ãããã©ã®ããã«åäœãããã確èªããããšãã§ããŸã: Internals of Windows ThreadããããŠä»åºŠã¯èªåã®ç®ã§èŠãŠã¿ãŸãããã次ã®ã³ãŒãã ãšããååã®ãã¡ã€ã«ã«ä¿åããŸãHelloWorldApp.java
ã
class HelloWorldApp {
public static void main(String []args) {
Runnable task = () -> {
try {
int secToWait = 1000 * 60;
Thread.currentThread().sleep(secToWait);
System.out.println("Woke up");
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread = new Thread(task);
thread.start();
}
}
ã芧ã®ãšããã60 ç§éåŸ
æ©ããã¿ã¹ã¯ãããããã®åŸããã°ã©ã ãçµäºããŸããã³ãã³ããjavac HelloWorldApp.java
ãã䜿çšããŠã³ã³ãã€ã«ããã ãã䜿çšããŠããã°ã©ã ãå®è¡ããŸãjava HelloWorldApp
ãããã°ã©ã ãå¥ã®ãŠã£ã³ããŠã§èµ·åããããšããå§ãããŸããããšãã°ãWindows ã§ã¯æ¬¡ã®ããã«ãªããŸãstart java HelloWorldApp
ãjps ã³ãã³ãã䜿çšã㊠PID (ããã»ã¹ ID) ãååŸããã ãã§ã¹ã¬ããã®ãªã¹ããéããŸããjvisualvm --openpid pid
ã芧 ã®ãšãããã¹ã¬ããã¯çŸåšãã¹ãªãŒãäžãã¹ããŒã¿ã¹ã«ãªã£ãŠããŸããå®éãããã解決ããããã®ããæŽç·Žãããæ¹æ³ããããŸããç§ãã¡ã®ã¹ã¬ããã«ã¯è¯ã倢ããããŸã:
try {
TimeUnit.SECONDS.sleep(60);
System.out.println("Woke up");
} catch (InterruptedException e) {
e.printStackTrace();
}
ãã¡ãã¡ã§æ±ã£ãŠããããšã«æ°ã¥ããŸãããInterruptedException
ïŒãã®çç±ãç解ããŸãããã
Thread.interrupt()
åé¡ã¯ãã¹ã¬ãããåŸ æ©äžãŸãã¯ã¹ãªãŒãäžã«ã誰ããäžæããããšããå¯èœæ§ããããšããããšã§ãããã®å Žåã ãåŠçããŸãInterruptedException
ããã®ã¡ã«ããºã ã¯ãThread.stop()
ã¡ãœãããéæšå¥šãšå®£èšãããåŸã«äœæãããŸãããã€ãŸããæ代é
ãã§æãŸãããªããã®ã§ãããã®çç±ã¯stop()
ãã¡ãœãããåŒã³åºããããšãã«ã¹ã¬ãããåçŽã«ã匷å¶çµäºããããããã§ãããããã¯éåžžã«äºæž¬äžå¯èœã§ãããã¹ã¬ããããã€åæ¢ããããã¯ããããŸããããããŒã¿ã®äžè²«æ§ãä¿èšŒã§ããŸããã§ãããã¹ã¬ããã匷å¶çµäºãããŠããéã«ãã¡ã€ã«ã«ããŒã¿ãæžã蟌ãã§ãããšæ³åããŠãã ãããJava ã®äœæè
ã¯ãã¹ã¬ããã匷å¶çµäºããããããã¹ã¬ãããäžæããããã«æ瀺ããæ¹ãè«ççã§ãããšå€æããŸããããã®æ
å ±ã«ã©ã®ããã«å¯Ÿå¿ãããã¯ãã¹ã¬ããèªäœã決å®ããåé¡ã§ãã詳现ã«ã€ããŠã¯ããThread.stop ãéæšå¥šã«ãªãã®ã¯ãªãã§ãã?ããåç
§ããŠãã ããããªã©ã¯ã«ã®ãŠã§ããµã€ãã§ãäŸãèŠãŠã¿ãŸããã:
public static void main(String []args) {
Runnable task = () -> {
try {
TimeUnit.SECONDS.sleep(60);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
};
Thread thread = new Thread(task);
thread.start();
thread.interrupt();
}
ãã®äŸã§ã¯ã60 ç§ã¯åŸ
ã¡ãŸããã代ããã«ãããã«ãäžæãããŸããããšè¡šç€ºãããŸããinterrupt()
ããã¯ãã¹ã¬ããäžã§ã¡ãœãããåŒã³åºããããã§ãããã®ã¡ãœããã¯ããå²ã蟌ã¿ã¹ããŒã¿ã¹ããšåŒã°ããå
éšãã©ã°ãèšå®ããŸããã€ãŸããåã¹ã¬ããã«ã¯çŽæ¥ã¢ã¯ã»ã¹ã§ããªãå
éšãã©ã°ããããŸãããã ãããã®ãã©ã°ãæäœããããã®ãã€ãã£ã ã¡ãœããããããŸãããããããããå¯äžã®æ¹æ³ã§ã¯ãããŸãããã¹ã¬ããã¯å®è¡äžã§ãããäœããåŸ
ã£ãŠããã®ã§ã¯ãªããåã«ã¢ã¯ã·ã§ã³ãå®è¡ããŠããã ãã§ããå¯èœæ§ããããŸããããããä»ã®äººãç¹å®ã®æéã«äœæ¥ãçµäºããããšèãããããããŸãããäŸãã°ïŒ
public static void main(String []args) {
Runnable task = () -> {
while(!Thread.currentThread().isInterrupted()) {
// Do some work
}
System.out.println("Finished");
};
Thread thread = new Thread(task);
thread.start();
thread.interrupt();
}
äžã®äŸã§ã¯ãwhile
ã¹ã¬ãããå€éšããäžæããããŸã§ã«ãŒããå®è¡ãããŸãããã©ã°ã«é¢ããŠã¯isInterrupted
ã ããã£ãããããšInterruptedException
isInterrupted ãã©ã°ããªã»ãããããisInterrupted()
false ãè¿ãããããšãç¥ã£ãŠããããšãéèŠã§ããThread ã¯ã©ã¹ã«ã¯ãçŸåšã®ã¹ã¬ããã«ã®ã¿é©çšãããéçãªThread.interrupted()ã¡ãœããããããŸããããã®ã¡ãœããã¯ãã©ã°ã false ã«ãªã»ããããŸãã詳现ã«ã€ããŠã¯ã ãã¹ã¬ããã®äžæããšããã¿ã€ãã«ã®ç« ãåç
§ããŠãã ããã
åå (å¥ã®ã¹ã¬ãããçµäºãããŸã§åŸ ã¡ãŸã)
æãåçŽãªã¿ã€ãã®åŸ æ©ã¯ãå¥ã®ã¹ã¬ãããçµäºããã®ãåŸ æ©ããããšã§ãã
public static void main(String []args) throws InterruptedException {
Runnable task = () -> {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
};
Thread thread = new Thread(task);
thread.start();
thread.join();
System.out.println("Finished");
}
ãã®äŸã§ã¯ãæ°ããã¹ã¬ãã㯠5 ç§éã¹ãªãŒãããŸããåæã«ãã¡ã€ã³ã¹ã¬ããã¯ãã¹ãªãŒãç¶æ
ã®ã¹ã¬ãããç®èŠããŠäœæ¥ãå®äºãããŸã§åŸ
æ©ããŸããJVisualVM ã§ã¹ã¬ããã®ç¶æ
ãèŠããšã次ã®ããã«ãªããŸãã ç£èŠããŒã«ã®ãããã§ãã¹ã¬ããã§äœãèµ·ãã£ãŠãããã確èªã§ããŸãããã®ã¡ãœããã¯ãåŒã³åºãããã¹ã¬ãããçããŠããéãjoin
å®è¡ããã Java ã³ãŒããå«ãã¡ãœããã«ãããªããããéåžžã«åçŽã§ããwait()
ã¹ã¬ãããçµäºãããš (äœæ¥ãçµäºãããš)ãåŸ
æ©ã¯äžæãããŸããããããã®ã¡ãœããã®éæ³ã®ãã¹ãŠã§ãjoin()
ãããã§ã¯ãæãèå³æ·±ãããšã«ç§»ããŸãããã
ã¢ãã¿ãŒ
ãã«ãã¹ã¬ããã«ã¯ã¢ãã¿ãŒã®æŠå¿µãå«ãŸããŠããŸããã¢ãã¿ãŒãšããèšèã¯ã16 äžçŽã®ã©ãã³èªãçµãŠè±èªã«äŒããããããã»ã¹ã芳å¯ããã§ãã¯ããŸãã¯ç¶ç¶çã«èšé²ããããã«äœ¿çšãããæ©åšãŸãã¯è£ 眮ããæå³ããŸãããã®èšäºã§ã¯ãåºæ¬çãªäºé ã«ã€ããŠèª¬æããŸãã詳现ãå¿ èŠãªå Žåã¯ããªã³ã¯å ã®è³æãåç §ããŠãã ããããŸã㯠Java èšèªä»æ§ (JLS): 17.1 ããå§ããŸããåæãããã¯æ¬¡ã®ããã«è¿°ã¹ãŠããŸã: Java ã¯ã¹ã¬ããéã®åæã«ãã¢ãã¿ãŒãã¡ã«ããºã ã䜿çšããŠããããšãå€æããŸãããã¢ãã¿ãŒã¯åãªããžã§ã¯ãã«é¢é£ä»ããããŠãããã¹ã¬ãã㯠ã§ã¢ãã¿ãŒãååŸãããlock()
ã ã§è§£æŸãããã§ããŸãunlock()
ã次ã«ãOracle ã® Web ãµã€ãã«ãããã¥ãŒããªã¢ã«ãIntrinsic Locks and SynchronizationããèŠã€ããŸããããã®ãã¥ãŒããªã¢ã«ã§ã¯ãJava ã®åæã¯ãåºæããã¯ãŸãã¯ã¢ãã¿ãŒ ããã¯ãšåŒã°ããå
éšãšã³ãã£ãã£ãäžå¿ã«æ§ç¯ãããŠãããšè¿°ã¹ãŠããŸãããã®ããã¯ã¯ãåã«ãã¢ãã¿ãŒããšåŒã°ããããšããããããŸãããŸããJava ã®ãã¹ãŠã®ãªããžã§ã¯ãã«ã¯ãããã«é¢é£ä»ããããåºæã®ããã¯ãããããšãããããŸãããJava çµã¿èŸŒã¿ããã¯ãšåæããåç
§ããŠãã ããã次ã«ãJava ã®ãªããžã§ã¯ããã¢ãã¿ãŒã«ã©ã®ããã«é¢é£ä»ããããšãã§ããããç解ããããšãéèŠã§ããJava ã§ã¯ãåãªããžã§ã¯ãã«ã¯ããããŒããããããã°ã©ããã³ãŒãããã¯å©çšã§ããªãããä»®æ³ãã·ã³ããªããžã§ã¯ããæ£ããæäœããããã«å¿
èŠãªå
éšã¡ã¿ããŒã¿ãæ ŒçŽãããŸãããªããžã§ã¯ã ããããŒã«ã¯ã次ã®ãããªãããŒã¯ ã¯ãŒãããå«ãŸããŠããŸãã
https://edu.netbeans.org/contrib/slides/java-overview-and-java-se6.pdf
public class HelloWorld{
public static void main(String []args){
Object object = new Object();
synchronized(object) {
System.out.println("Hello World");
}
}
}
ããã§ãçŸåšã®ã¹ã¬ãã (ãããã®ã³ãŒãè¡ãå®è¡ãããã¹ã¬ãã) ã¯ãsynchronized
ããŒã¯ãŒãã䜿çšããŠãobject"\
ããã¯ãååŸ/ååŸããããã®å€æ°ãä»ã«ã¢ãã¿ãŒãäºã人ãããªãå Žå (ã€ãŸããåããªããžã§ã¯ãã䜿çšããŠåæã³ãŒããå®è¡ããŠãã人ãä»ã«ããªãå Žå)ãJava ã¯ããã€ã¢ã¹ ããã¯ããšåŒã°ããæé©åãå®è¡ããããšããå ŽåããããŸããé¢é£ããã¿ã°ãšãã©ã®ã¹ã¬ãããã¢ãã¿ãŒã®ããã¯ãææããŠãããã«é¢ããã¬ã³ãŒããããªããžã§ã¯ã ããããŒã®ããŒã¯ ã¯ãŒãã«è¿œå ãããŸããããã«ãããã¢ãã¿ãŒãããã¯ããããã«å¿
èŠãªãªãŒããŒãããã軜æžãããŸããã¢ãã¿ãŒã以åã«å¥ã®ã¹ã¬ããã«ãã£ãŠææãããŠããå Žåããã®ãããªããã¯ã ãã§ã¯ååã§ã¯ãããŸãããJVM ã¯æ¬¡ã®ã¿ã€ãã®ããã¯ããåºæ¬ããã¯ãã«åãæ¿ããŸããæ¯èŒäº€æ (CAS) æäœã䜿çšããŸããããã«ããªããžã§ã¯ã ããããŒã®ããŒã¯ ã¯ãŒãèªäœã¯ããŒã¯ ã¯ãŒããä¿åããã®ã§ã¯ãªããããŒã¯ ã¯ãŒããä¿åãããŠããå Žæãžã®åç
§ãä¿åããããã«ãªããåºæ¬ããã¯ã䜿çšããŠããããšã JVM ãç解ã§ããããã«ã¿ã°ãå€æŽãããŸããè€æ°ã®ã¹ã¬ãããã¢ãã¿ãŒãããã£ãŠç«¶å (競å) ããå Žå (1 ã€ã¯ããã¯ãååŸãããã 1 ã€ã¯ããã¯ã解æŸãããã®ãåŸ
ã£ãŠãã)ãããŒã¯ ã¯ãŒãå
ã®ã¿ã°ãå€æŽãããããŒã¯ ã¯ãŒãã¯ã¢ãã¿ãŒãžã®åç
§ãä¿åããããã«ãªããŸãããªããžã§ã¯ããšã㊠- JVM ã®å
éšãšã³ãã£ãã£ãJDK Enchancement Proposal (JEP) ã§è¿°ã¹ãããŠããããã«ããã®ç¶æ³ã§ã¯ããã®ãšã³ãã£ãã£ãä¿åããããã«ã¡ã¢ãªã®ãã€ãã£ã ããŒãé åã«ã¹ããŒã¹ãå¿
èŠã§ãããã®å
éšãšã³ãã£ãã£ã®ã¡ã¢ãªäœçœ®ãžã®åç
§ã¯ããªããžã§ã¯ã ããããŒã®ããŒã¯ ã¯ãŒãã«ä¿åãããŸãããããã£ãŠãã¢ãã¿ãŒã¯å®éã«ã¯ãè€æ°ã®ã¹ã¬ããéã§å
±æãªãœãŒã¹ãžã®ã¢ã¯ã»ã¹ãåæããããã®ã¡ã«ããºã ã§ããJVM ã¯ããã®ã¡ã«ããºã ã®ããã€ãã®å®è£
ãåãæ¿ããŸãããããã£ãŠãããããããããããã«ãã¢ãã¿ãŒã«ã€ããŠè©±ããšãã¯ãå®éã«ã¯ããã¯ã«ã€ããŠè©±ããŠããããšã«ãªããŸãã次ã«ãããŒã¯ ã¯ãŒãå
ã®ã¿ã°ãå€æŽãããããŒã¯ ã¯ãŒãã¯ã¢ãã¿ãŒãžã®åç
§ããªããžã§ã¯ã (JVM ã®å
éšãšã³ãã£ãã£) ãšããŠä¿åããŸããJDK Enchancement Proposal (JEP) ã§è¿°ã¹ãããŠããããã«ããã®ç¶æ³ã§ã¯ããã®ãšã³ãã£ãã£ãä¿åããããã«ã¡ã¢ãªã®ãã€ãã£ã ããŒãé åã«ã¹ããŒã¹ãå¿
èŠã§ãããã®å
éšãšã³ãã£ãã£ã®ã¡ã¢ãªäœçœ®ãžã®åç
§ã¯ããªããžã§ã¯ã ããããŒã®ããŒã¯ ã¯ãŒãã«ä¿åãããŸãããããã£ãŠãã¢ãã¿ãŒã¯å®éã«ã¯ãè€æ°ã®ã¹ã¬ããéã§å
±æãªãœãŒã¹ãžã®ã¢ã¯ã»ã¹ãåæããããã®ã¡ã«ããºã ã§ããJVM ã¯ããã®ã¡ã«ããºã ã®ããã€ãã®å®è£
ãåãæ¿ããŸãããããã£ãŠãããããããããããã«ãã¢ãã¿ãŒã«ã€ããŠè©±ããšãã¯ãå®éã«ã¯ããã¯ã«ã€ããŠè©±ããŠããããšã«ãªããŸãã次ã«ãããŒã¯ ã¯ãŒãå
ã®ã¿ã°ãå€æŽãããããŒã¯ ã¯ãŒãã¯ã¢ãã¿ãŒãžã®åç
§ããªããžã§ã¯ã (JVM ã®å
éšãšã³ãã£ãã£) ãšããŠä¿åããŸããJDK Enchancement Proposal (JEP) ã§è¿°ã¹ãããŠããããã«ããã®ç¶æ³ã§ã¯ããã®ãšã³ãã£ãã£ãä¿åããããã«ã¡ã¢ãªã®ãã€ãã£ã ããŒãé åã«ã¹ããŒã¹ãå¿
èŠã§ãããã®å
éšãšã³ãã£ãã£ã®ã¡ã¢ãªäœçœ®ãžã®åç
§ã¯ããªããžã§ã¯ã ããããŒã®ããŒã¯ ã¯ãŒãã«ä¿åãããŸãããããã£ãŠãã¢ãã¿ãŒã¯å®éã«ã¯ãè€æ°ã®ã¹ã¬ããéã§å
±æãªãœãŒã¹ãžã®ã¢ã¯ã»ã¹ãåæããããã®ã¡ã«ããºã ã§ããJVM ã¯ããã®ã¡ã«ããºã ã®ããã€ãã®å®è£
ãåãæ¿ããŸãããããã£ãŠãããããããããããã«ãã¢ãã¿ãŒã«ã€ããŠè©±ããšãã¯ãå®éã«ã¯ããã¯ã«ã€ããŠè©±ããŠããããšã«ãªããŸãããããŠãããŒã¯ ã¯ãŒãã¯ãã¢ãã¿ãŒãžã®åç
§ããªããžã§ã¯ã (JVM ã®å
éšãšã³ãã£ãã£) ãšããŠä¿åããããã«ãªããŸãããJDK Enchancement Proposal (JEP) ã§è¿°ã¹ãããŠããããã«ããã®ç¶æ³ã§ã¯ããã®ãšã³ãã£ãã£ãä¿åããããã«ã¡ã¢ãªã®ãã€ãã£ã ããŒãé åã«ã¹ããŒã¹ãå¿
èŠã§ãããã®å
éšãšã³ãã£ãã£ã®ã¡ã¢ãªäœçœ®ãžã®åç
§ã¯ããªããžã§ã¯ã ããããŒã®ããŒã¯ ã¯ãŒãã«ä¿åãããŸãããããã£ãŠãã¢ãã¿ãŒã¯å®éã«ã¯ãè€æ°ã®ã¹ã¬ããéã§å
±æãªãœãŒã¹ãžã®ã¢ã¯ã»ã¹ãåæããããã®ã¡ã«ããºã ã§ããJVM ã¯ããã®ã¡ã«ããºã ã®ããã€ãã®å®è£
ãåãæ¿ããŸãããããã£ãŠãããããããããããã«ãã¢ãã¿ãŒã«ã€ããŠè©±ããšãã¯ãå®éã«ã¯ããã¯ã«ã€ããŠè©±ããŠããããšã«ãªããŸãããããŠãããŒã¯ ã¯ãŒãã¯ãã¢ãã¿ãŒãžã®åç
§ããªããžã§ã¯ã (JVM ã®å
éšãšã³ãã£ãã£) ãšããŠä¿åããããã«ãªããŸãããJDK Enchancement Proposal (JEP) ã§è¿°ã¹ãããŠããããã«ããã®ç¶æ³ã§ã¯ããã®ãšã³ãã£ãã£ãä¿åããããã«ã¡ã¢ãªã®ãã€ãã£ã ããŒãé åã«ã¹ããŒã¹ãå¿
èŠã§ãããã®å
éšãšã³ãã£ãã£ã®ã¡ã¢ãªäœçœ®ãžã®åç
§ã¯ããªããžã§ã¯ã ããããŒã®ããŒã¯ ã¯ãŒãã«ä¿åãããŸãããããã£ãŠãã¢ãã¿ãŒã¯å®éã«ã¯ãè€æ°ã®ã¹ã¬ããéã§å
±æãªãœãŒã¹ãžã®ã¢ã¯ã»ã¹ãåæããããã®ã¡ã«ããºã ã§ããJVM ã¯ããã®ã¡ã«ããºã ã®ããã€ãã®å®è£
ãåãæ¿ããŸãããããã£ãŠãããããããããããã«ãã¢ãã¿ãŒã«ã€ããŠè©±ããšãã¯ãå®éã«ã¯ããã¯ã«ã€ããŠè©±ããŠããããšã«ãªããŸãããã®å
éšãšã³ãã£ãã£ã®ã¡ã¢ãªäœçœ®ãžã®åç
§ã¯ããªããžã§ã¯ã ããããŒã®ããŒã¯ ã¯ãŒãã«ä¿åãããŸãããããã£ãŠãã¢ãã¿ãŒã¯å®éã«ã¯ãè€æ°ã®ã¹ã¬ããéã§å
±æãªãœãŒã¹ãžã®ã¢ã¯ã»ã¹ãåæããããã®ã¡ã«ããºã ã§ããJVM ã¯ããã®ã¡ã«ããºã ã®ããã€ãã®å®è£
ãåãæ¿ããŸãããããã£ãŠãããããããããããã«ãã¢ãã¿ãŒã«ã€ããŠè©±ããšãã¯ãå®éã«ã¯ããã¯ã«ã€ããŠè©±ããŠããããšã«ãªããŸãããã®å
éšãšã³ãã£ãã£ã®ã¡ã¢ãªäœçœ®ãžã®åç
§ã¯ããªããžã§ã¯ã ããããŒã®ããŒã¯ ã¯ãŒãã«ä¿åãããŸãããããã£ãŠãã¢ãã¿ãŒã¯å®éã«ã¯ãè€æ°ã®ã¹ã¬ããéã§å
±æãªãœãŒã¹ãžã®ã¢ã¯ã»ã¹ãåæããããã®ã¡ã«ããºã ã§ããJVM ã¯ããã®ã¡ã«ããºã ã®ããã€ãã®å®è£
ãåãæ¿ããŸãããããã£ãŠãããããããããããã«ãã¢ãã¿ãŒã«ã€ããŠè©±ããšãã¯ãå®éã«ã¯ããã¯ã«ã€ããŠè©±ããŠããããšã«ãªããŸãã
åææžã¿ (ããã¯ãåŸ æ©äž)
åã«èŠãããã«ããåæãããã¯ã(ãŸãã¯ãã¯ãªãã£ã«ã« ã»ã¯ã·ã§ã³ã) ã®æŠå¿µã¯ã¢ãã¿ãŒã®æŠå¿µãšå¯æ¥ã«é¢é£ããŠããŸããäŸãèŠãŠã¿ãŸããã:
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
Runnable task = () -> {
synchronized(lock) {
System.out.println("thread");
}
};
Thread th1 = new Thread(task);
th1.start();
synchronized(lock) {
for (int i = 0; i < 8; i++) {
Thread.currentThread().sleep(1000);
System.out.print(" " + i);
}
System.out.println(" ...");
}
}
ããã§ãã¡ã€ã³ã¹ã¬ããã¯æåã«ã¿ã¹ã¯ ãªããžã§ã¯ããæ°ããã¹ã¬ããã«æž¡ããããã«ããã¯ãååŸããŠãããã«å¯ŸããŠé·ãæäœ (8 ç§) ãå®è¡ããŸãããã®éãã£ãšãã¿ã¹ã¯ã¯synchronized
ããã¯ããã§ã«ååŸãããŠãããããããã¯ã«å
¥ãããšãã§ããªããããç¶è¡ã§ããŸãããã¹ã¬ãããããã¯ãååŸã§ããªãå Žåãã¹ã¬ããã¯ã¢ãã¿ãŒãåŸ
ã¡ãŸããããã¯ãååŸãããšããã«å®è¡ãç¶è¡ããŸããã¹ã¬ãããã¢ãã¿ãŒãçµäºãããšãããã¯ã解æŸãããŸããJVisualVM ã§ã¯ã次ã®ããã«ãªããŸãã JVisualVM ã§ãããããã«ãã¹ããŒã¿ã¹ã¯ãMonitorãã§ããããã¯ãã¹ã¬ããããããã¯ãããŠãããã¢ãã¿ãŒãååŸã§ããªãããšãæå³ããŸããã³ãŒãã䜿çšããŠã¹ã¬ããã®ã¹ããŒã¿ã¹ã決å®ããããšãã§ããŸããããã®æ¹æ³ã§æ±ºå®ãããã¹ããŒã¿ã¹ã®ååã¯ãJVisualVM ã§äœ¿çšãããååãšã¯äŒŒãŠããŸãããäžèŽããŸããããã®å Žåãth1.getState()
for ã«ãŒãå
ã®ã¹ããŒãã¡ã³ãã¯BLOCKEDãè¿ããŸããããã¯ãã«ãŒããå®è¡ãããŠããéããlock
ãªããžã§ã¯ãã®ã¢ãã¿ãŒãã¹ã¬ããã«ãã£ãŠå æããmain
ãth1
ã¹ã¬ããã¯ãããã¯ãããããã¯ã解æŸããããŸã§ç¶è¡ã§ããªãããã§ããåæããããããã¯ã«å ããŠãã¡ãœããå
šäœãåæããããšãã§ããŸããããšãã°ãHashTable
ã¯ã©ã¹ã®ã¡ãœããã¯æ¬¡ã®ãšããã§ãã
public synchronized int size() {
return count;
}
ãã®ã¡ãœããã¯ãåžžã« 1 ã€ã®ã¹ã¬ããã«ãã£ãŠã®ã¿å®è¡ãããŸããæ¬åœã«ããã¯ãå¿
èŠã§ãã? ã¯ããå¿
èŠã§ããã€ã³ã¹ã¿ã³ã¹ ã¡ãœããã®å Žåãããã®ããªããžã§ã¯ã (çŸåšã®ãªããžã§ã¯ã) ãããã¯ãšããŠæ©èœããŸãããã®ãããã¯ã«é¢ããèå³æ·±ãè°è«ãããã«ãããŸã:åæãããã¯ã®ä»£ããã«åæã¡ãœããã䜿çšããå©ç¹ã¯ãããŸãã? ãã¡ãœãããéçã§ããå Žåãããã¯ã¯ãthisããªããžã§ã¯ãã§ã¯ãªã (éçã¡ãœããã«ã¯ãthisããªããžã§ã¯ãããªããã)ãClass ãªããžã§ã¯ã (ããšãã°ãInteger.class
) ã«ãªããŸãã
åŸ ã¡ãŸãïŒã¢ãã¿ãŒãåŸ ã£ãŠããŸãïŒãNotice() ã¡ãœãããš NotifyAll() ã¡ãœãã
Thread ã¯ã©ã¹ã«ã¯ãã¢ãã¿ãŒã«é¢é£ä»ããããå¥ã®åŸ æ©ã¡ãœããããããŸããsleep()
ããšã¯ç°ãªãjoin()
ããã®ã¡ãœããã¯åçŽã«åŒã³åºãããšã¯ã§ããŸããããã®åã¯wait()
ããã®wait
ã¡ãœããã¯ãåŸ
æ©ããã¢ãã¿ãŒã«é¢é£ä»ãããããªããžã§ã¯ãäžã§åŒã³åºãããŸããäŸãèŠãŠã¿ãŸããã:
public static void main(String []args) throws InterruptedException {
Object lock = new Object();
// The task object will wait until it is notified via lock
Runnable task = () -> {
synchronized(lock) {
try {
lock.wait();
} catch(InterruptedException e) {
System.out.println("interrupted");
}
}
// After we are notified, we will wait until we can acquire the lock
System.out.println("thread");
};
Thread taskThread = new Thread(task);
taskThread.start();
// We sleep. Then we acquire the lock, notify, and release the lock
Thread.currentThread().sleep(3000);
System.out.println("main");
synchronized(lock) {
lock.notify();
}
}
JVisualVM ã§ã¯ã次ã®ããã«ãªããŸãã ãããã©ã®ããã«æ©èœããããç解ããã«ã¯ãwait()
ããã³notify()
ã¡ãœããã ã«é¢é£ä»ããããŠããããšãæãåºããŠãã ããjava.lang.Object
ãã¹ã¬ããé¢é£ã®ã¡ãœãããObject
ã¯ã©ã¹å
ã«ããã®ã¯å¥åŠã«æãããããããŸããããããããã®çç±ãä»æããã«ãªããŸãããJava ã®ãã¹ãŠã®ãªããžã§ã¯ãã«ã¯ããããŒãããããšãæãåºããŠãã ãããããããŒã«ã¯ãã¢ãã¿ãŒã«é¢ããæ
å ±ãã€ãŸãããã¯ã®ã¹ããŒã¿ã¹ãªã©ã®ããŸããŸãªããŠã¹ããŒãã³ã°æ
å ±ãå«ãŸããŠããŸããåãªããžã§ã¯ããŸãã¯ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã¯ãåºæããã¯ãŸãã¯ã¢ãã¿ãŒãšåŒã°ãã JVM ã®å
éšãšã³ãã£ãã£ã«é¢é£ä»ããããŠããããšã«æ³šæããŠãã ãããäžã®äŸã§ã¯ãã¿ã¹ã¯ ãªããžã§ã¯ãã®ã³ãŒãã¯ããªããžã§ã¯ãã«é¢é£ä»ããããã¢ãã¿ãŒã®åæãããã¯ã«å
¥ãããšã瀺ããŠããŸãlock
ããã®ã¢ãã¿ãŒã®ããã¯ã®ååŸã«æåãããšãwait()
ãšåŒã°ããŸããã¿ã¹ã¯ãå®è¡ããŠããã¹ã¬ããã¯lock
ãªããžã§ã¯ãã®ã¢ãã¿ãŒã解æŸããŸããããªããžã§ã¯ãã®ã¢ãã¿ãŒããã®éç¥ãåŸ
ã€ã¹ã¬ããã®ãã¥ãŒã«å
¥ããŸãlock
ããã®ã¹ã¬ããã®ãã¥ãŒã¯ WAIT SET ãšåŒã°ãããã®ç®çãããé©åã«åæ ããŠããŸããã€ãŸãããã¥ãŒãšãããããã»ããã«è¿ããã®ã§ããã¹ã¬ããmain
ã¯ã¿ã¹ã¯ ãªããžã§ã¯ãã䜿çšããŠæ°ããã¹ã¬ãããäœæããéå§ã㊠3 ç§åŸ
æ©ããŸããããã«ãããæ°ããã¹ã¬ãããã¹ã¬ãããããå
ã«ããã¯ãååŸãmain
ãã¢ãã¿ãŒã®ãã¥ãŒã«å
¥ãå¯èœæ§ãé«ããªããŸãããã®åŸãmain
ã¹ã¬ããèªèº«ããªããžã§ã¯ãã®åæãããã¯ã«å
¥ãlock
ãã¢ãã¿ãŒã䜿çšããŠã¹ã¬ããéç¥ãå®è¡ããŸããéç¥ãéä¿¡ãããåŸãmain
ã¹ã¬ããã¯lock
lock
ãªããžã§ã¯ãã®ã¢ãã¿ãŒã解æŸããããšããªããžã§ã¯ãã®ã¢ãã¿ãŒã解æŸãããã®ãåŸ
ã£ãŠããæ°ããã¹ã¬ãããå®è¡ãç¶ç¶ããŸããnotify()
éç¥ã 1 ã€ã®ã¹ã¬ããã«ã®ã¿éä¿¡ããããšã ( )ããã¥ãŒå
ã®ãã¹ãŠã®ã¹ã¬ããã«åæã«éä¿¡ããããšãã§ããŸã( notifyAll()
)ã詳现ã«ã€ããŠã¯ããJava ã® Notice() ãš NoticeAll() ã®éãããåç
§ããŠãã ãããéç¥ã®é åºã¯ JVM ã®å®è£
æ¹æ³ã«ãã£ãŠç°ãªãããšã«æ³šæããããšãéèŠã§ãã詳现ã¯ãã¡ããã芧ãã ãã:éç¥ãšéç¥ã䜿çšããŠé£¢é€ã解決ããã«ã¯ã©ãããã°ããã§ãã? ããªããžã§ã¯ããæå®ããã«åæãå®è¡ã§ããŸããããã¯ãåäžã®ã³ãŒã ãããã¯ã§ã¯ãªãã¡ãœããå
šäœãåæãããå Žåã«å®è¡ã§ããŸããããšãã°ãéçã¡ãœããã®å Žåãããã¯ã¯ Class ãªããžã§ã¯ãã«ãªããŸã ( ãä»ããŠååŸ.class
)ã
public static synchronized void printA() {
System.out.println("A");
}
public static void printB() {
synchronized(HelloWorld.class) {
System.out.println("B");
}
}
ããã¯ã®äœ¿çšãšããç¹ã§ã¯ãã©ã¡ãã®æ¹æ³ãåãã§ããinstance
ã¡ãœãããéçã§ãªãå Žåãåæã¯çŸåšã® ãã€ãŸã ã䜿çšããŠå®è¡ãããŸãthis
ããšããã§ãå
ã»ã©ãgetState()
ã¡ãœããã䜿çšããŠã¹ã¬ããã®ã¹ããŒã¿ã¹ãååŸã§ãããšè¿°ã¹ãŸãããwait()
ããšãã°ãã¢ãã¿ãŒãåŸ
æ©ããŠãããã¥ãŒå
ã®ã¹ã¬ããã®å Žåãã¡ãœããã§ã¿ã€ã ã¢ãŠããæå®ãããŠãã å Žåãã¹ããŒã¿ã¹ã¯ WAITING ãŸã㯠TIMED_WAITING ã«ãªããŸãã
https://stackoverflow.com/questions/36425942/what-is-the-lifecycle-of-thread-in-java
ã¹ã¬ããã®ã©ã€ããµã€ã¯ã«
ã¹ã¬ããã®ã¹ããŒã¿ã¹ã¯ããã®åç¶æéäžã«å€åããŸããå®éããããã®å€æŽã¯ã¹ã¬ããã®ã©ã€ããµã€ã¯ã«ãæ§æããŸããã¹ã¬ãããäœæããããšããã«ããã®ã¹ããŒã¿ã¹ã¯ NEW ã«ãªããŸãããã®ç¶æ ã§ã¯ãæ°ããã¹ã¬ããã¯ãŸã å®è¡ãããŠããããJava ã¹ã¬ãã ã¹ã±ãžã¥ãŒã©ã¯ããã«ã€ããŠãŸã äœãèªèããŠããŸãããã¹ã¬ãã ã¹ã±ãžã¥ãŒã©ãã¹ã¬ããã«ã€ããŠåŠç¿ããã«ã¯ãthread.start()
ã¡ãœãããåŒã³åºãå¿
èŠããããŸãããã®åŸãã¹ã¬ãã㯠RUNNABLE ç¶æ
ã«ç§»è¡ããŸããã€ã³ã¿ãŒãããã«ã¯ããå®è¡å¯èœãç¶æ
ãšãå®è¡äžãç¶æ
ãåºå¥ãã誀ã£ãå³ããããããããŸããããããããã¯ééãã§ããJava ã¯ãåäœæºåå®äºã(å®è¡å¯èœ) ãšãåäœäžã(å®è¡äž) ãåºå¥ããªãããã§ããã¹ã¬ããã¯çããŠãããã¢ã¯ãã£ãã§ã¯ãªã (å®è¡å¯èœã§ã¯ãªã) å Žåã次㮠2 ã€ã®ç¶æ
ã®ããããã«ãªããŸãã
- BLOCKED â ã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ãã€ãŸã
synchronized
ãããã¯ã«å ¥ãã®ãåŸ ã£ãŠããŸãã - WAITING â å¥ã®ã¹ã¬ãããäœããã®æ¡ä»¶ãæºããã®ãåŸ ã£ãŠããŸãã
getState()
ã¡ãœããã䜿çšããŸããã¹ã¬ããã«ã¯isAlive()
ãã¹ã¬ãããçµäºããŠããªãå Žåã« true ãè¿ãã¡ãœããããããŸãã
LockSupport ãšã¹ã¬ããããŒãã³ã°
Java 1.6 ãããLockSupportãšåŒã°ããèå³æ·±ãã¡ã«ããºã ãç»å ŽããŸããã ãã®ã¯ã©ã¹ã¯ããèš±å¯ããããã䜿çšããåã¹ã¬ããã«é¢é£ä»ããŸããpark()
èš±å¯ãå©çšå¯èœãªå Žåãã¡ãœããã®åŒã³åºãã¯ããã«æ»ãããã®éçšã§èš±å¯ãæ¶è²»ããŸãããã以å€ã®å Žåã¯ãããã¯ãããŸãããã®unpark
ã¡ãœãããåŒã³åºããšãèš±å¯ããŸã å©çšå¯èœã§ãªãå Žåã«å©çšå¯èœã«ãªããŸããèš±å¯èšŒã¯1ã€ã ãã§ããã® Java ããã¥ã¡ã³ãã§ã¯ãLockSupport
ãã®Semaphore
ã¯ã©ã¹ã«ã€ããŠèšåããŠããŸããç°¡åãªäŸãèŠãŠã¿ãŸãããã
import java.util.concurrent.Semaphore;
public class HelloWorldApp{
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(0);
try {
semaphore.acquire();
} catch (InterruptedException e) {
// Request the permit and wait until we get it
e.printStackTrace();
}
System.out.println("Hello, World!");
}
}
çŸåšã»ããã©ã®èš±å¯ã 0 ã§ããããããã®ã³ãŒãã¯åžžã«åŸ
æ©ããŸããacquire()
ã³ãŒãå
㧠ãåŒã³åºããã (ã€ãŸããèš±å¯ãèŠæ±ãã) ãšãã¹ã¬ããã¯èš±å¯ãåãåããŸã§åŸ
æ©ããŸããåŸ
ã£ãŠããã®ã§ã ãåŠçããå¿
èŠããããŸãInterruptedException
ãèå³æ·±ãããšã«ãã»ããã©ã¯å¥ã®ã¹ã¬ããç¶æ
ãååŸããŸããJVisualVM ãèŠããšãç¶æ
ããåŸ
æ©ãã§ã¯ãªããããŒã¯ãã§ããããšãããããŸãã å¥ã®äŸãèŠãŠã¿ãŸãããã
public static void main(String[] args) throws InterruptedException {
Runnable task = () -> {
// Park the current thread
System.err.println("Will be Parked");
LockSupport.park();
// As soon as we are unparked, we will start to act
System.err.println("Unparked");
};
Thread th = new Thread(task);
th.start();
Thread.currentThread().sleep(2000);
System.err.println("Thread state: " + th.getState());
LockSupport.unpark(th);
Thread.currentThread().sleep(2000);
}
ã¹ã¬ããã®ã¹ããŒã¿ã¹ã¯ WAITING ã«ãªããŸãããJVisualVM ã¯ããŒã¯ãŒãwait
ã«ãããã®synchronized
ãšpark
ã¯ã©ã¹ã«ãããã®ãåºå¥ããŸãLockSupport
ããªããããLockSupport
ããã»ã©éèŠãªã®ã§ãããã? ããäžåºŠ Java ããã¥ã¡ã³ãã«æ»ã£ãŠãWAITINGã¹ã¬ããã®ç¶æ
ãèŠãŠã¿ãŸããããã芧ã®ãšãããããã«å
¥ãæ¹æ³ã¯ 3 ã€ãããããŸããããã®ãã¡ã® 2 ã€ã®æ¹æ³ã¯ ãšwait()
ã§ãjoin()
ããããŠ3ã€ç®ã¯ ã§ãLockSupport
ãJava ã§ã¯ãããã¯ãäžã«æ§ç¯ããŠLockSuppor
ãããé«ã¬ãã«ã®ããŒã«ãæäŸããããšãã§ããŸããäžã€äœ¿ã£ãŠã¿ãŸããããããšãã°ã次ãèŠãŠãã ããReentrantLock
ã
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class HelloWorld{
public static void main(String []args) throws InterruptedException {
Lock lock = new ReentrantLock();
Runnable task = () -> {
lock.lock();
System.out.println("Thread");
lock.unlock();
};
lock.lock();
Thread th = new Thread(task);
th.start();
System.out.println("main");
Thread.currentThread().sleep(2000);
lock.unlock();
}
}
åã®äŸãšåæ§ã«ãããã§ã¯ãã¹ãŠãåçŽã§ãããªããžã§ã¯ãlock
ã¯èª°ããå
±æãªãœãŒã¹ã解æŸããã®ãåŸ
ã¡ãŸããmain
JVisualVM ãèŠããšãã¹ã¬ãããããã¯ã解æŸãããŸã§æ°ããã¹ã¬ãããããŒã¯ãããããšãããããŸããããã¯ã®è©³çŽ°ã«ã€ããŠã¯ããJava 8 StampedLocks vs. ReadWriteLocks and Synchronized and Lock API in Javaããåç
§ããŠãã ãããããã¯ã®å®è£
æ¹æ³ãããããç解ããã«ã¯ããã®èšäºã Guide to the Java Phaserã㧠Phaser ã«ã€ããŠèªããšåœ¹ç«ã¡ãŸãããŸããããŸããŸãªã·ã³ã¯ããã€ã¶ãŒã«ã€ããŠèšãã°ã Java ã·ã³ã¯ããã€ã¶ãŒã«é¢ãã DZone ã®èšäºãå¿
ããèªã¿ãã ããã
çµè«
ãã®ã¬ãã¥ãŒã§ã¯ãJava ã§ã¹ã¬ããã察話ããäž»ãªæ¹æ³ã調ã¹ãŸãããè¿œå è³æ:- Java ãš Thread ã¯ã©ã¹ãçµã¿åããããšããã«å¹æçã§ããããŒã I â å®è¡ã¹ã¬ãã
- https://dzone.com/articles/the-java-synchronizers
- https://www.javatpoint.com/java-multithreading-interview-questions
GO TO FULL VERSION