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)); // , ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); while (true) { AsynchronousSocketChannel channel = accept(listener); // executorService.submit(new Runnable() { @Override public void run() { Coro.initSuspended(new ICoroRunnable() { @Async({@Await("handle")}) public void run() { // - , // handle(channel); } }).start(); } }); } } }).start(); } @Async({@Await("read"), @Await("write")}) public static void handle(AsynchronousSocketChannel channel) { ByteBuffer buffer = ByteBuffer.allocate(10 * 1024); Integer read = read(channel, buffer); // write(channel, outBuffer); // channel.close(); }
æ£ããã³ã³ãã€ã«ã«å¿ èŠãªäžéšã®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; // + 3: ifnull 0000 // - + 6: invokestatic org/jcoro/Coro.popState:()Ljava/lang/Integer; // popState() null, + 9: dup + 10: ifnull 32 // - + 13: invokestatic org/jcoro/Coro.isUnpatchableCall:()Z // + 16: ifeq 23 + 19: invokestatic org/jcoro/Coro.popRef:()Ljava/lang/Object; + 22: pop + 23: ldc 0 + 25: invokestatic org/jcoro/Coro.setUnpatchableCall:(Z)V + 28: pop + 29: goto 43 + 32: pop 0000: invokestatic org/jcoro/Coro.get:()Lorg/jcoro/Coro; // 0003: astore 5 0005: aload 5 + 40: goto 0007 // - + 43: invokestatic org/jcoro/Coro.popRef:()Ljava/lang/Object; + 46: checkcast "Lorg/jcoro/Coro;" + 49: astore 5 + 51: invokestatic org/jcoro/Coro.popRef:()Ljava/lang/Object; + 54: checkcast "Ljava/lang/String;" + 57: astore 4 + 59: invokestatic org/jcoro/Coro.popDouble:()D + 62: dstore_2 + 63: invokestatic org/jcoro/Coro.popInt:()I + 66: istore_1 + 67: invokestatic org/jcoro/Coro.popRef:()Ljava/lang/Object; + 70: checkcast "Lorg/jcoro/tests/SimpleTest$1;" + 73: astore_0 + 74: invokestatic org/jcoro/Coro.popRef:()Ljava/lang/Object; + 77: checkcast "Lorg/jcoro/Coro;" 0007: invokevirtual org/jcoro/Coro.yield:()V // + 83: invokestatic org/jcoro/Coro.isYielding:()Z // - + 86: ifeq 0010 + 89: aload_0 + 90: invokestatic org/jcoro/Coro.pushRef:(Ljava/lang/Object;)V + 93: iload_1 + 94: invokestatic org/jcoro/Coro.pushInt:(I)V + 97: dload_2 + 98: invokestatic org/jcoro/Coro.pushDouble:(D)V + 101: aload 4 + 103: invokestatic org/jcoro/Coro.pushRef:(Ljava/lang/Object;)V + 106: aload 5 + 108: invokestatic org/jcoro/Coro.pushRef:(Ljava/lang/Object;)V + 111: aload_0 + 112: invokestatic org/jcoro/Coro.pushRef:(Ljava/lang/Object;)V + 115: ldc 0 + 117: invokestatic org/jcoro/Coro.pushState:(I)V + 120: aconst_null // null, + 121: areturn 0010: ldc "returnedStr" // 0012: areturn
ã¡ãœããã®æåã«ã埩æ§ãã€ã³ããèå¥ããã³ãŒããè¿œå ãããŸããã埩æ§ãã€ã³ãã®ååŸã«ã¯ã埩å ããã³ä¿åããã³ãŒããè¿œå ãããŸããã ããå€ãã®åŸ©æ§ãã€ã³ããããå Žåãæåã«ãåçŽãªç§»è¡ã®ä»£ããã«ãåãæ¿ãã衚瀺ãããŸãã ãã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ã䜿çšããæãç°¡åãªæ¹æ³ã§ãã