ãã®åéã®ç ç©¶ã¯ãã
éåæïŒããã¯ãã¥ã¶ãã¥ãŒãã£ãŒããšããèšäºã«è§ŠçºãããŸããã ãã®äžã§ãèè
ã¯ã
ã³ã«ãŒãã³ã䜿çšããŠãéåžžã®åæã³ãŒããšåãããã«èŠããããã«éåæã³ãŒããåçŽåããããšãå¯èœã§ããããéåææäœã®äœ¿çšã«ãã£ãŠåŸããããã³ãºãä¿æããæ¹æ³ã®ã¢ã€ãã¢ã説æããŸãã èŠããã«ãã¢ãããŒãã®æ¬è³ªã¯ããã§ãïŒå®è¡ã³ã³ããã¹ããä¿åããã³åŸ©å
ã§ããã¡ã«ããºã ãããå ŽåïŒã³ã«ãŒãã³ã®ãµããŒãïŒãã³ãŒã«ããã¯ãã§ãŒã³ã®ã³ãŒã
startReadSocket((data) -> { startWriteFile(data, (result) -> { if (result == ok) ... }); });
次ã®ããã«æžãæããããšãã§ããŸãã
data = readSocket(); result = writeFile(data); if (result == ok) ...
ããã§ãreadSocketïŒïŒããã³writeFileïŒïŒã¯ãéåææäœã次ã®ããã«åŒã³åºãããã³ã«ãŒãã³ã§ãã
byte[] readSocket() { byte[] result = null; startReadSocket((data) -> { result = data; resume(); }); yield(); return result; }
yieldïŒïŒããã³resumeïŒïŒã¡ãœããã¯ããã¹ãŠã®ãã¬ãŒã ãšããŒã«ã«å€æ°ãšãšãã«å®è¡ã³ã³ããã¹ããä¿åããã³åŸ©å
ããŸãã æ¬¡ã®ããšãèµ·ãããŸããreadSocketïŒïŒãåŒã³åºããšããstartReadSocketïŒïŒãåŒã³åºããŠyieldïŒïŒãå®è¡ããããšã§éåææäœãèšç»ããŸãã YieldïŒïŒã¯å®è¡ã³ã³ããã¹ããä¿åããã¹ã¬ããã¯çµäºããŸãïŒããŒã«ã«æ»ããŸãïŒã éåææäœãå®äºãããšãã³ãŒã«ããã¯ãçµäºããåã«resumeïŒïŒãåŒã³åºããŠãã³ãŒãã®å®è¡ãåéããŸãã ã³ã³ãããŒã«ã¯åã³writeFileïŒïŒãåŒã³åºãã¡ã€ã³é¢æ°ãåãåããŸãã writeFileïŒïŒã¯æ§é ã䌌ãŠããããã¹ãŠãç¹°ãè¿ãããŸãã
䜿çšããããã¹ãŠã®éåææäœã«å¯ŸããŠäžåºŠãã®ãããªå€æãè¡ããååŸãã颿°ãã©ã€ãã©ãªã«é
眮ãããšãéåžžã®åæã³ãŒãã§ãããã®ããã«éåæã³ãŒããäœæã§ããããŒã«ãåŸãããŸãã åæã³ãŒãïŒå¯èªæ§ã䟿å©ãªãšã©ãŒåŠçïŒãšéåæïŒããã©ãŒãã³ã¹ïŒã®å©ç¹ãçµã¿åãããæ©äŒãåŸãããŸãã ãã®å©äŸ¿æ§ã«å¯Ÿããæ¯æãã¯ãäœããã®åœ¢ã§å®è¡ã³ã³ããã¹ããä¿åããã³åŸ©å
ããå¿
èŠãããããšã§ãã ãã®èšäºã§ã¯ãèè
ã¯C ++ã§ã®å®è£
ã«ã€ããŠèª¬æããŠããŸãããJavaã§ãã®ãããªãã®ãååŸãããã£ãã®ã§ãã ããã«ã€ããŠèª¬æããŸãã
javaflow
ãŸããJVMã®ã³ã«ãŒãã³ã®å®è£
ãèŠã€ããå¿
èŠããããŸããã ããã€ãã®ãªãã·ã§ã³ã®äžã§ãjavaflowã©ã€ãã©ãªãæãé©ããŠããããšã倿ããŸããã å®éšã«ã¯éåžžã«é©ããŠããŸãããæ®å¿µãªããããããžã§ã¯ãã¯é·ãéæŸæ£ãããŠããŸãã çæãããã³ãŒãã«ã¯ã³ãïŒéã³ã³ãã€ã©ãŒïŒãæ¿å
¥ãããšãjavaflowã«ããã€ãã®é倧ãªåé¡ãããããšãããããŸããã
- ã©ã ãã¯ãŸã£ãããµããŒããããŠããŸããã ã©ã€ãã©ãªã®æåŸã®ãªãªãŒã¹ã2008幎ã§ãã£ãããšãèãããšãããã¯é©ãããšã§ã¯ãããŸããã
- ã³ãŒãã®ã€ã³ã¹ãã«ã¡ã³ãã¯éåžžã«äžååã§ããã¡ãœããå
ã®ãã¹ãŠã®åŒã³åºãã¯ã€ã³ã¹ãã«ã¡ã³ããããŸããããããã®ã»ãšãã©ã¯ãµã¹ãã³ãïŒïŒã³ãŒã«ã«ã€ãªããããšã¯ãããŸããã ãã®çµæããã€ãã³ãŒãã倧ããèšãã¿ãå®éã«ã¯ãã®ãããªã¢ãããŒãã¯åãå
¥ããããã»ã©åäœãé
ããªããŸãã
- åå°ã®ãµããŒãã¯ãããŸããã ã³ãŒãã®å®è¡äžã«ãªãã¬ã¯ã·ã§ã³ãä»ããŠã¡ãœãããåŒã³åºãããšãã§ããå Žåãjavaflowã¯ãã®å Žæã§å®è¡ã³ã³ããã¹ããä¿åããã³åŸ©å
ã§ããŸããã ãããŠãããã¯æ¥åžžã®ããã°ã©ãã³ã°ã§ã¯éåžžã«éèŠã§ãããååçãªå¯èœæ§ã®åé¡ã§ãããããŸããããã»ãšãã©ãã¹ãŠã®äººããªãã¬ã¯ã·ã§ã³ãä»ããŠæ©èœããDIã³ã³ããã䜿çšããŠãããšããäºå®ã§ãã ãããã£ãŠããªãã¬ã¯ã·ã§ã³ãçŠæ¢ããããšã¯ã§ããŸãã;ããã¯ããã°ã©ããŒã«ãšã£ãŠéåžžã«åŒ·ãå¶éã§ãã
ããã«ãããããããjavaflowã¯ç¶æ
ãä¿åããã³åŸ©å
ããæ¹æ³ãèŠã€ããã®ã«åœ¹ç«ã¡ãŸããã ãã®åŸã2ã€ã®ãªãã·ã§ã³ããããŸãããjavaflowããµããŒãããããå®è£
ãäœæããŠãã ããã æãããªçç±ïŒèŽåœçãªæ¬ é¥ïŒã®ããã2çªç®ã®æ¹æ³ãéžæãããŸããã
ãžã§ã€ã³ã
ååšããªãèšèªã«è¿œå ãããã³ã«ãŒãã³ã¯ããããæ¡åŒµããŸãã ææ¡ãããã¢ãããŒããå®å
šã«æŽ»çšããåæã«èªãããšã®ãªãã¢ããªã±ãŒã·ã§ã³ãäœæããã«ã¯ããããã䟿å©ã«ããå¿
èŠããããŸãã ã³ãŒããèªããšããã®é¢æ°ãã³ã«ãŒãã³ã§ãããéåææäœãå®è¡ããããšãããã«ãããã¯ãã§ãããããã£ãŠãã¹ã¿ãã¯ã®ä¿åãšåŸ©å
ã®ãµããŒãã®ã³ã³ããã¹ãå
ã§èµ·åããå¿
èŠããããŸãã CïŒã«ã¯ããã®ããã®asyncããã³awaitããŒã¯ãŒãããããŸãã Javaã§ã¯ãæ®å¿µãªãããããŒã¯ãŒãã远å ããããšã¯çŸå®çã§ã¯ãããŸããããã¢ãããŒã·ã§ã³ã䜿çšã§ããŸãã ãã¡ãããããã¯ãã¹ãŠããã°ããŸãããã©ãããã°ããã®ã§ãããã ä»ã®äœããåºãŠãããããããŸãã ãããŸã§ã®éããã®ããã«ïŒ
Coro coro = Coro.initSuspended(new ICoroRunnable() { @Override @Async({@Await("foo")}) public void run() { int i = 5; double f = 10; final String argStr = foo(i, f, "argStr"); } @Async(@Await("yield")) private String foo(int x, double y, String m) { Coro c = Coro.get(); c.yield(); return "returnedStr"; } }); coro.start(); coro.resume();
@Asyncã¢ãããŒã·ã§ã³ã®ååšã¯ãjcoroã«ãã®ã¡ãœããã®ãã€ãã³ãŒããã€ã³ã¹ãã«ã¡ã³ãããã³ã«ãŒãã³ã«ããããã«æç€ºããŸãã 埩æ§ãã€ã³ãã®çœ²åã¯ã@ Awaitã¢ãããŒã·ã§ã³ã«ãã£ãŠå®çŸ©ãããŸãã @ Awaitã¢ãããŒã·ã§ã³ã®ãªã¹ãã«çœ²åãå«ãŸããã³ã«ãŒãã³å
ã®ãã¹ãŠã®åŒã³åºããå埩ãã€ã³ãã«ãªããŸãã jcoroã®ã³ã«ãŒãã³ã¯ã@ Asyncã¢ãããŒã·ã§ã³ã§ããŒã¯ãããå°ãªããšã1ã€ã®åŸ©å
ãã€ã³ããæã€ã¡ãœããã§ãã ã¡ãœããã«åäžã®åŸ©å
ãã€ã³ãããªãå Žåãã€ã³ã¹ãã«ã¡ã³ããããŸããã 埩å
ãã€ã³ãã¯ãCoro.yieldïŒïŒãžã®åŒã³åºãããŸãã¯æçµçã«Coro.yieldïŒïŒãžã®åŒã³åºãã«ã€ãªããå¯èœæ§ã®ããåŒã³åºãïŒã³ã«ãŒãã³ïŒã§ãã
äžèšã®äŸã§ã¯ã©ããªããŸããïŒæåã«ãCoroã€ã³ã¹ã¿ã³ã¹ãäœæãããŸããããã¯ãã³ã«ãŒãã³ã®ä¿åç¶æ
ãä¿åããèµ·åãä¿ââåãããã³åŸ©å
ã§ãããªããžã§ã¯ãã§ãã æåã¯ãã³ã«ãŒãã³ã¯åæåãããã ãã§ãããéå§ãããŸããã startïŒïŒãåŒã³åºããããšãã³ã³ãããŒã«ã¯runïŒïŒã¡ãœãããååŸããŸãããã®ã¡ãœããã¯ãŸããç¶æ
ã埩å
ããå¿
èŠããããã©ããããã§ãã¯ããŸãã ãããŸã§ã®ãšãããã³ã«ãŒãã³ãéå§ããrunïŒïŒããã®ã³ãŒãã®å®è¡ãéå§ããŸããã ã¡ãœããã¯ã³ãŒããå®è¡ããfooïŒïŒãåŒã³åºããŸãã fooïŒïŒå
ã§ã¯ãåããã§ãã¯ãå®è¡ãããŸã-ç¶æ
ã埩å
ããå¿
èŠããããŸããïŒ çãã¯ãããããã§ãåæ§ã«ãã¡ãœããã³ãŒãã¯æåããå®è¡ãéå§ããŸãã ããããyieldïŒïŒãåŒã³åºããšã次ã®ããšãèµ·ãããŸãã yieldïŒïŒåŒã³åºãèªäœã¯ãisYieldingããã©ã°ãèšå®ããã ãã§ãä»ã«ã¯äœãããŸããããåŒã³åºãåŸã®ã³ãŒãã¯ãã®ãã©ã°ãèŠãŠãå®è¡ãç¶ç¶ããããã®ç¶æ
ãä¿æããŠããã«çµäºããnullãè¿ããŸãã åãããšã1ã¬ãã«äžã«èµ·ãããŸãã ãããŠãstartïŒïŒã¡ãœããã¯å¶åŸ¡ãè¿ããŸãã ãã®æç¹ã§äœããããŸããïŒ yieldïŒïŒã®åŒã³åºããå®è¡ãããåã®ã³ãŒãã¯ãå®è¡ã¹ããŒã¿ã¹ãCoroã€ã³ã¹ã¿ã³ã¹ã«ä¿åãããŸãã æ¬¡ã«ãresumeïŒïŒãåŒã³åºããŸãã ããã«ãããrunïŒïŒã¡ãœãããå床åŒã³åºãããŸãã ãŸããåããŠã®å Žåãšåæ§ã«ããã®ã¡ãœããã¯åŸ©å
ãå¿
èŠãã©ããã確èªããŸãã ä»åã¯æ¬åœã«è¡ãå¿
èŠããããã¡ãœããã¯fooïŒïŒã®åŒã³åºãã§åæ¢ããããšãæãåºããŠãããŒã«ã«å€æ°ãšã¹ã¿ãã¯ã埩å
ãããã®åã«ãã£ãã³ãŒããå®è¡ããã«åŒã³åºãfooïŒïŒã«çŽæ¥è¡ããŸãã fooïŒïŒã¡ãœããã§ãåãããšãèµ·ãããŸããã¹ã¿ãã¯å€æ°ãšããŒã«ã«å€æ°ã埩å
ããããã«yieldïŒïŒåŒã³åºãã«é²ã¿ãŸãã yieldïŒïŒãåç¬ã§åŒã³åºããšãå
éšãã©ã°ããªã»ãããããŸãã ãã®åŸãfooïŒïŒã¡ãœããã¯æååãreturnedStrããè¿ãããšã§å®è¡ãå®äºããŸãã runïŒïŒã¡ãœãããæ®ããŸãããããæ£åžžã«å®äºããresumeïŒïŒãåŒã³åºãã³ãŒãã«å¶åŸ¡ãæ»ããŸãã åºåã§ã¯ãå®å
šã«è§£æ±ºãããã³ã«ãŒãã³ãããããã®å®è£
ã¯2ã€ã®éšåã«åãããŠããŸãã
ããã¯éåæã¢ããªã±ãŒã·ã§ã³ã®äœæã«ã©ã®ããã«åœ¹ç«ã¡ãŸããïŒ
ãªã¯ãšã¹ãã«å¿ããŠããŒã¿ããŒã¹ã«ã¢ã¯ã»ã¹ããããŒã¿ãåŠçããŠãããã³ãã¬ãŒãã«é©çšããããŒã¯ã¢ãããè¿ããµãŒããŒã¢ããªã±ãŒã·ã§ã³ãäœæããå¿
èŠããããšããŸãã ã¯ã©ã·ãã¯WebãµãŒããŒã¢ããªã±ãŒã·ã§ã³ã ã»ãšãã©ãã¹ãŠã®æ®µéã§ãéåææäœã䜿çšã§ããŸãã æ¥ç¶ã®ç¢ºç«ãèŠæ±ã®åä¿¡æã®ãœã±ããããã®ããŒã¿ã®èªã¿åããããŒã¿ããŒã¹ãšã®ãã¹ãŠã®ãããã¯ãŒã¯æäœããã³ãã¬ãŒãã®ããŒãæã®ãã¡ã€ã«ã®èªã¿åããçµæã®ãœã±ãããžã®éä¿¡ã ãã®ã·ããªãªã®CPUã¯ãéåææäœãããŒã¿ååŠçããžãã¯ãããã³ãã³ãã¬ãŒãã®èšç»ã§ã®ã¿å¿ããã¯ãã§ãã æ®ãã®æéãããã»ããµã¯äŒãããšãã§ããŸãã ãããã³ãŒãã§ã©ã®ããã«æŽçã§ããããèããŠã¿ãŸãããã ãµãŒããŒãã¹ã±ããããŸãããïŒ
public static void main(String[] args) { Coro.initSuspended(new ICoroRunnable() { @Async({@Await("accept")}) public void run() { final AsynchronousServerSocketChannel listener = bind(new InetSocketAddress(5000));
æ£ããã³ã³ãã€ã«ã«å¿
èŠãªäžéšã®try-catchãããã¯ã¯ã³ãŒãã§çç¥ãããŠããŸããããã¯ãã³ãŒããèªã¿ãããããããã«è¡ãããŸãã
ãã³ãã«å
ã«ã¯ãä»»æã®ããžãã¯ã远å ã§ããŸãã ããšãã°ããã³ã³ãããŒã©ãŒããå®çŸ©ãããªãã¬ã¯ã·ã§ã³ãäŸåæ§æ³šå
¥ãéããŠãããåŒã³åºããŸãã ãã ãããªãã¬ã¯ã·ã§ã³ã©ã€ãã©ãªãŸãã¯ã€ã³ã¹ãã«ã¡ã³ãåãããŠããªãã©ã€ãã©ãªãä»ãããªã«ããªãã€ã³ããå«ãã³ãŒãã®åŒã³åºãã«ã¯æ³šæããå¿
èŠããããŸãã 詳现ã«ã€ããŠã¯ã以äžãã芧ãã ããã
ã¹ããªãŒã 䜿çšçã®èгç¹ãããããã¯æ¬¡ã®ããã«æ©èœããŸãã ã¯ãŒã«ãŒã¹ã¬ããã®ããŒã«ããããéåææäœã®ã³ãŒã«ããã¯ãå®è¡ããããã«JVMãäºçŽããã·ã¹ãã ã¹ã¬ããããŒã«ããããŸãã éåææäœãå®äºãããšãã¹ã¬ããã®1ã€ãã³ãŒã«ããã¯ãéå§ããŸãã ãŸããã³ã«ãŒãã³ã®ç¶æ
ã埩å
ãããæ¬¡ã«ã³ã«ãŒãã³ã®å®è¡ãç¶ç¶ãããå®äºãŸãã¯æ¬¡ã®éåææäœã«å°éããŸãã ã³ã«ãŒãã³ãçµäºããåŸïŒãŸãã¯æ¬¡ã®éåææäœãã¹ã±ãžã¥ãŒã«ããåŸã«å®è¡ãäžæåæ¢ããåŸïŒãã¹ã¬ããã¯ããŒã«ã«æ»ããŸãã ãããã£ãŠã1ã€ã®ãªã¯ãšã¹ããå¥ã®ã¹ã¬ããã§é çªã«åŠçããããšãã§ããããã«ããã³ãŒãã«ããã€ãã®å¶éã課ããããŸãã ãããã£ãŠãããšãã°ãputãšgetã®éã§ã³ã«ãŒãã³ã®å®è¡ãäžæãããªããšããç¢ºå®æ§ããªãå Žåãã¹ã¬ããããŒã«ã«å€æ°ã䜿çšã§ããŸããã äžæ¹ãåè·¯ã¯æé©ã«è¿ãããã«èŠããè¯å¥œãªããã©ãŒãã³ã¹ãçŽæããŸãã
å®è£
javaflowãšã¯ç°ãªããjcoroã¯ãã¹ãŠã®ã¡ãœãããšãã®äžã®ãã¹ãŠã®åŒã³åºããèšæž¬ããŸããã ã€ã³ã¹ãã«ã¡ã³ããŒã·ã§ã³ã®å¯Ÿè±¡ãšãªãã®ã¯ã³ã«ãŒãã³ã®ã¿ã§ã-å°ãªããšã1ã€ã®åŸ©å
ãã€ã³ããããã¡ãœããã 埩å
ãã€ã³ãã¯ãå®è¡ããããšæçµçã«yieldïŒïŒã®åŒã³åºãã«ã€ãªããåŒã³åºãã§ãã ã€ãŸããããã¯ãã¹ãŠã®èª²é¡ã§çºçããå¿
èŠã¯ãªããçè«çãªå¯èœæ§ã§ååã§ãã éåžžãã³ãŒãã¯ã©ã®ããã«èšæž¬ãããŸããïŒ ã¹ã¬ããå
šäœã®å®è¡ç¶æ
ãä¿åããã³åŸ©å
ããã«ã¯ã©ãããã°ããã§ããïŒ ããã¯ãŸã£ããé£ããããšã§ã¯ãªãããšãããããŸããã ã³ã«ãŒãã³ã®èªãããã¿ã€ãã«ã§ãããšäž»åŒµããåæ¹æ³ãå°ããªç¶æ
æ©æ¢°ã«å€ããã®ã«ååã§ãã ãããè¡ãã«ã¯ãã¡ãœããã®å
é ã«ãã€ãã³ãŒãã远å ããŸããããã¯ãå埩ããå¿
èŠããªãå Žåã¯äœãè¡ããŸãããå¿
èŠã«å¿ããŠåãæ¿ãïŒç¶æ
ïŒãå®è¡ããç¶æ
ã®å€ã«ãã£ãŠãå®è¡ãäžæãããå埩ãã€ã³ãã®åŒã³åºãã«åãæ¿ããŸãã ç¶æ
ã®ä¿åã¯ãªã«ããªãã€ã³ãã®åŒã³åºãæã«ã®ã¿çºçãããããããã§ååã§ãïŒyieldïŒïŒã®åŒã³åºãèªäœããªã«ããªãã€ã³ãã§ãïŒã ããã«å ããŠãããŒã«ã«å€æ°ãšãã¬ãŒã ã¹ã¿ãã¯ã埩å
ããããšãå¿ããªãã§ãã ããã JVMã®ãã¬ãŒã ã®ç¶æ
ã¯ãã®ã»ããïŒã¹ã¿ãã¯ã®ç¶æ
ãããŒã«ã«å€æ°ãçŸåšã®åœä»€ïŒã«ãã£ãŠäžæã«èå¥ãããããããã®åŸã¯ãã¹ãŠãæ£åžžã«æ©èœããŠãããšäž»åŒµã§ããŸãã åæ§ã«ãå®è¡ã¹ã¿ãã¯å
šäœã§save-restoreãå®è¡ããŸãã
äŸã«æ»ã£ãŠããããã©ããªããèŠãŠã¿ãŸãããã
@Async(@Await("yield")) private String foo(int a, double b, String c) { Coro c = Coro.get(); c.yield(); return "returnedStr"; }
ãã®ã³ã«ãŒãã³ã¯äœã®åœ¹ã«ãç«ãããäœæ¥ãäžæåæ¢ããã ãã§ããã®åŸå€ãè¿ããŸãã ãã€ãã³ãŒãã§ã¯ã次ã®ããã«ãªããŸãã
private java.lang.String foo(int, double, java.lang.String); descriptor: (IDLjava/lang/String;)Ljava/lang/String; flags: ACC_PRIVATE Code: stack=1, locals=6, args_size=4 0000: invokestatic org/jcoro/Coro.get:()Lorg/jcoro/Coro; 0003: astore 5 0005: aload 5 0007: invokevirtual org/jcoro/Coro.yield:()V 0010: ldc "returnedStr" 0012: areturn
ã€ã³ã¹ãã«ã¡ã³ããŒã·ã§ã³åŸãããã衚瀺ãããŸãïŒçµæã¯çµ±äžãããå·®åã®åœ¢åŒã«ãªããŸãããæ®å¿µãªããHabrã¯æååã®åŒ·èª¿è¡šç€ºããµããŒãããŠããŸããïŒã
private java.lang.String foo(int, double, java.lang.String); descriptor: (IDLjava/lang/String;)Ljava/lang/String; flags: ACC_PRIVATE Code: - stack=1, locals=6, args_size=4 + stack=2, locals=6, args_size=4 + 0: invokestatic org/jcoro/Coro.getSafe:()Lorg/jcoro/Coro;
ã¡ãœããã®æåã«ã埩æ§ãã€ã³ããèå¥ããã³ãŒãã远å ãããŸããã埩æ§ãã€ã³ãã®ååŸã«ã¯ã埩å
ããã³ä¿åããã³ãŒãã远å ãããŸããã ããå€ãã®åŸ©æ§ãã€ã³ããããå Žåãæåã«ãåçŽãªç§»è¡ã®ä»£ããã«ãåãæ¿ãã衚瀺ãããŸãã ãã1ã€åŸ®åŠãªéãããããŸãã 䞊åã¹ã¿ãã¯ã䜿çšããŠãã¬ãŒã ãä¿åããã³åŸ©å
ããããããªããžã§ã¯ãã远å ããã³åä¿¡ããé åºã«åŸãå¿
èŠããããŸãã æåã«ãªããžã§ã¯ãAãã¹ã¿ãã¯ã«é
眮ããæ¬¡ã«Bãé
眮ããå Žåãããããéã®é åºã§åãåãå¿
èŠããããŸãã ãããã£ãŠãæåã«ããŒã«ã«å€æ°ãä¿åããæ¬¡ã«ãã¬ãŒã ã¹ã¿ãã¯ãä¿åããå Žåãéã«åŸ©å
ãå®è¡ããå¿
èŠããããŸãã ãããŠãããã§ã®ãã©ã¹ã¯ãåŒã³åºããªããžã§ã¯ããžã®åç
§ã®åŠçã§ãïŒããïŒã ä¿åãããšã極端ãªã¹ã¿ãã¯ãšããŠã¹ã¿ãã¯ã«ããã·ã¥ããããªã«ããªäžã«æåã«ååŸãããŸãïŒãã¡ããããªã«ããªãã€ã³ããééçãªæ¹æ³ã§ãªãéãïŒã äžèšã®äŸã«ã¯ããŒã«ã«å€æ°ã¯ãããŸãããããããã䜿çšãããšã³ãŒãã¯ã»ãŒåãã«ãªããŸãã
ãããã§ããªãã³ãŒã
æ®å¿µãªãããã¹ã¿ãã¯ãä¿åããã³åŸ©å
ããããã®äžèšã®æŠç¥ã¯ããã¹ãŠã®ã³ã«ãŒãã³ãèšæž¬ã§ããå Žåã«ã®ã¿æ©èœããŸãã ãªã«ããªãã€ã³ããå«ãã¡ãœãããã€ã³ã¹ãã«ã¡ã³ãã§ããªãå Žåããã®æŠç¥ã¯æ©èœããŸããã ããã¯ãåå°ãŸãã¯ã€ã³ã¹ãã«ã¡ã³ãã§ããªãã©ã€ãã©ãªãä»ããŠã³ãŒããåŒã³åºãå Žåã«å¯èœã§ãã ãããŠããŸã ã©ã€ãã©ãªã䜿çšããŠäœããèããããšãã§ããå Žåãåå°ãªãã§ããŸããæ¹æ³ã¯ãããŸããã ãã¹ãŠã®ããã°ã©ããŒã¯ãDIã³ã³ãããŒããããã·ãŒãããã³AOPã䜿çšããããšèããŠããŸãã ãã ããã»ãšãã©ã®å Žåããããã®ã¿ã€ãã®åŒã³åºãã¯å®å
šã«ã¹ããŒãã¬ã¹ã§ããã€ãŸããåŒã³åºããè¡ããªãåŒã³åºãã®æ°ã¯ãåºæ¬çã«å¶åŸ¡ãããã«è»¢éããã ãã§ãã ãããŠãã³ã«ãŒãã³ãåéãããšãã«ããã®ã¡ãœãããããäžåºŠåŒã³åºãããšãã§ããŸããåãã¡ãœããã«åŒæ°ãæž¡ãã ãã§ãã ãããŠã圌ãåŒã³åºãã³ãŒãã§ã¯ãç¶æ
ã埩å
ãç¶ããŠããŸãã ãŸãããã®ã¡ã«ããºã ããµããŒãããã«ã¯ã2çªç®ã®ç¶æ
ä¿åæŠç¥ã®ã¿ãå¿
èŠã§ãããã®æŠç¥ã§ã¯ãåŒã³åºãã®åŸã§ã¯ãªãåŒã³åºãã®åã«åŒæ°ãä¿åãããŸãã ãã®æŠç¥ã¯çŸåšjcoroã§ãµããŒããããŠããã䜿çšããã«ã¯ããªã«ããªãã€ã³ãã@AwaitïŒpatchable = falseïŒãšããŠããŒã¯ããå¿
èŠããããŸãã
ã¡ãœããã®åŒã³åºããåæŠç¥ã䜿çšããããšã«é¢ããæ
å ±ã¯ã
wikiã§èŠã€ããããšãã§ã
ãŸã ã
LambdãµããŒã
ã©ã ãã¯ãµããŒããããŠããŸãããæ²ãã£ãŠããŸãã 2ã€ã®åé¡ããããŸãã ãã®1ã€ã¯ãJavaã§ã¯ã©ã ãã«æ³šéãä»ããã®ãé£ãããããã«èªã¿ã«ããããšã§ãã ç§ãèŠã€ããå¯äžã®è§£æ±ºçã¯ãæè¿ç»å Žããã¿ã€ã泚éã«åºã¥ããŠãããæ¬¡ã®ããã«ãªããŸãïŒ
Coro coro = Coro.initSuspended((@Async({@Await(value = "yield")}) ICoroRunnable) () -> { Coro.get().yield(); });
ã³ã³ãã€ã©ã¯ãããèªèãããšãã¯ã©ã¹ãã¡ã€ã«ã«æ³šéã远å ãããããinvokedynamicåœä»€ã«é¢é£ä»ããŸãã ãããŠãããã¯åäœããŸãããæ®å¿µãªãããåžžã«ã§ã¯ãããŸããã ã³ã³ãã€ã©ã¯ããã®ãããªæ³šéããã®åœä»€ã§ã¯ãªã以åã®åœä»€ã«é¢é£ä»ããå ŽåãããïŒããããããã¯ãã°ã§ãïŒãå Žåã«ãã£ãŠã¯ã¯ã©ã¹ãã¡ã€ã«ã«æ³šéããŸã£ããæžã蟌ãŸãªãããšããããŸãã ããšãã°ãããã¯ãã®ãããªã³ãŒããã³ã³ãã€ã«ãããšãã«èµ·ãããŸãïŒ
public static void main(String[] args) { Runnable one = (@TypeAnn("1") Runnable) () -> { Runnable two = (@TypeAnn("2") Runnable) () -> { Runnable three = (@TypeAnn("3") Runnable) () -> { Runnable four = (@TypeAnn("4") Runnable) () -> { }; }; }; }; }
ã¯ã©ã¹ãã¡ã€ã«ã§ã¯ãå€åŽã®2ã€ã®ã©ã ãã®invokedynamicåœä»€ã®ã¿ã«æ³šéãä»ããããŸãã ãŸããã³ã³ãã€ã©ãŒã¯ãå
åŽã®2ã€ã®ã©ã ãã®æ³šéãç¡èŠããŸãã ããããã°ã§ããå¯èœæ§ãé«ããããOracleã«éä¿¡ããŸãããã確èªã¯ãŸã åããŠããŸããã ãããããŸãããããšãé¡ã£ãŠããŸãã
2çªç®ã®åé¡ã¯ãã©ã ããJavaã®äžçã§ã¯ããªãå¥åŠãªçãç©ã§ããããšã§ãã ãããã¯ã€ã³ã¹ã¿ã³ã¹ã¡ãœãããšåŒã°ããŸãããå®éã«ã¯éçã¡ãœããã§ãã ãããŠããã®æ³¢åç²åã®äºéæ§ã¯ãä¿å修埩ã¡ã«ããºã ã®æŠå¿µçãªåé¡ãçã¿åºããŸãã äºå®ãæé©ãªãªã«ããªæŠç¥ãå®çŸããã«ã¯ããããã€ã³ã¹ã¿ã³ã¹ã¡ãœããã®æ¬äœã«ä¿åããå¿
èŠããããŸãïŒ
å³ãåç
§ïŒã ãã ããåŒã³åºãå
ã®ã³ãŒãã®ã¿ãæ©èœã€ã³ã¿ãŒãã§ã€ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãžã®ãªã³ã¯ãæã£ãŠããŸãïŒ æåŸã«ãã©ã ããå®è¡ããåã«åŒæ°ã®ä¿åãã€ãŸãpatchable = falseïŒãªãã¬ã¯ã·ã§ã³ã®åé¡ãåé¿ããããšãç®çãšããïŒãšåããªãã·ã§ã³ã䜿çšããå¿
èŠããããŸãã ãããŠãããã¯ãã£ãšãã£ããåããŸãã ãã ããåã©ã ãã³ã«ãŒãã³ã§patchable = falseãç»é²ããå¿
èŠãããããã«çããäžäŸ¿ãšæ¯èŒããŠãããããããã¯éèŠã§ã¯ãããŸããã
ããã2ã€ã®åé¡ããŸãšãããšãæ®å¿µãªçµè«ãå°ãåºãããšãã§ããŸããã©ã ãã³ã«ãŒãã³ããŸã 䜿çšããããšã¯ãå§ãã§ããŸããã
çŸåšã®ç¶æ³ãšèšç»
ãã®ãããžã§ã¯ãã¯
https://github.com/elw00d/jcoroã§å
¥æã§ã
ãŸã ã ãšã³ãžã³ããã®
ãã¹ãã®ã»ãã ãããã³ããã€ãã®
äŸãå©çšå¯èœã«ãªããŸããã ãã¯ãããžãŒãæãèµ·ããããã«ã¯ã次ã®ããšãè¡ãå¿
èŠããããŸãã
- â stack map frames
- maven gradle jar- class-
- , 3 . , â ( nio, jcoro), â jcoro. , - , . , .
- . . . , , jdbc. - «» jdbc, â mysql, postgresql, mssql. â jcoro, . â - -.
- IntelliJ IDEA, . - , ( @Await , @Async) .
- , User Guide .
ããªããããžãã¹ã§jcoroãå©ããã詊ããŠã¿ãããšãã顿ãæã£ãŠãããªããããããïŒãããªãã¯ã³ãã¥ãã±ãŒã·ã§ã³ã§ã¯ãããããGithub Issuesã䜿çšããæãç°¡åãªæ¹æ³ã§ãã