Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
JVM ²¢·¢ÐÔ: Java ºÍ Scala ²¢·¢ÐÔ»ù´¡
 
×÷Õß Dennis Sosnoski£¬»ðÁú¹ûÈí¼þ    ·¢²¼ÓÚ 2014-09-05
  2724  次浏览      27
 

Á˽â Java ÓïÑÔÖеIJ¢·¢ÐÔºÍ Scala ÌṩµÄ¸½¼ÓÑ¡Ïî

Java? ƽ̨¶ÔËùÓлùÓÚ JVM µÄÓïÑÔÖеIJ¢·¢±à³ÌÌṩÁËÓÅÐãµÄÖ§³Ö¡£Scala À©Õ¹ÁË Java ÓïÑÔÖеIJ¢·¢ÐÔÖ§³Ö£¬ÌṩÁ˸ü¶àÔÚ´¦ÀíÆ÷Ö®¼ä¹²Ïí¹¤×÷ºÍЭµ÷½á¹ûµÄ·½Ê½¡£±¾ÎÄÊÇÒ»¸öÓÐ¹Ø JVM ²¢·¢ÐÔµÄÐÂϵÁеÚһƪ£¬½«½éÉÜ Java 7 ÖÐ×îеIJ¢·¢ÐÔ±à³Ì¹¦ÄÜ£¬»¹½«½éÉÜһЩ Scala ÔöÇ¿¡£±¾ÎÄ»¹Îª°ïÖúÄúÀí½â Java 8 ÖеIJ¢·¢ÐÔÌØÐÔɨÇåÁËÕϰ­¡£

´¦ÀíÆ÷ËÙ¶ÈÊýÊ®ÄêÀ´Ò»Ö±³ÖÐø¿ìËÙ·¢Õ¹£¬²¢ÔÚÊÀ¼Í½»ÌæÖ®¼Ê×ßµ½ÁËÖյ㡣´ÓÄÇʱÆð£¬´¦ÀíÆ÷ÖÆÔìÉ̸ü¶àµØÊÇͨ¹ýÔö¼ÓºËÐÄÀ´Ìá¸ßоƬÐÔÄÜ£¬¶ø²»ÔÙͨ¹ýÔö¼ÓʱÖÓËÙÂÊÀ´Ìá¸ßоƬÐÔÄÜ¡£¶àºËϵͳÏÖÔÚ³ÉΪÁË´ÓÊÖ»úµ½ÆóÒµ·þÎñÆ÷µÈËùÓÐÉ豸µÄ±ê×¼£¬¶øÕâÖÖÇ÷ÊÆ¿ÉÄܼÌÐø²¢ÓÐËù¼ÓËÙ¡£¿ª·¢ÈËÔ±Ô½À´Ô½ÐèÒªÔÚËûÃǵÄÓ¦ÓóÌÐò´úÂëÖÐÖ§³Ö¶à¸öºËÐÄ£¬ÕâÑù²ÅÄÜÂú×ãÐÔÄÜÐèÇó¡£

ÔÚ±¾ÏµÁÐÎÄÕÂÖУ¬Äú½«Á˽âһЩÕë¶Ô Java ºÍ Scala ÓïÑԵIJ¢·¢±à³ÌµÄз½·¨£¬°üÀ¨ Java ÈçºÎ½« Scala ºÍÆäËû»ùÓÚ JVM µÄÓïÑÔÖÐÒѾ­Ì½Ë÷³öÀ´µÄÀíÄî½áºÏÔÚÒ»Æð¡£µÚÒ»ÆÚÎÄÕ½«½éÉÜһЩ±³¾°£¬Í¨¹ý½éÉÜ Java 7 ºÍ Scala µÄһЩ×îм¼Êõ£¬°ïÖúÁ˽â JVM ÉϵIJ¢·¢±à³ÌµÄÈ«¾°¡£Äú½«Á˽âÈçºÎʹÓà Java ExecutorService ºÍ ForkJoinPool ÀàÀ´¼ò»¯²¢·¢±à³Ì¡£»¹½«Á˽âһЩ½«²¢·¢±à³ÌÑ¡ÏîÀ©Õ¹µ½´¿ Java ÖеÄÒÑÓй¦ÄÜÖ®ÍâµÄ»ù±¾ Scala ÌØÐÔ¡£Ôڴ˹ý³ÌÖУ¬Äú»á¿´µ½²»Í¬µÄ·½·¨¶Ô²¢·¢±à³ÌÐÔÄÜÓкÎÓ°Ïì¡£ºóÐø¼¸ÆÚÎÄÕ½«»á½éÉÜ Java 8 ÖеIJ¢·¢ÐԸĽøºÍһЩÀ©Õ¹£¬°üÀ¨ÓÃÓÚÖ´ÐпÉÀ©Õ¹µÄ Java ºÍ Scala ±à³ÌµÄ Akka ¹¤¾ß°ü¡£

Java ²¢·¢ÐÔÖ§³Ö

ÔÚ Java ƽ̨µ®ÉúÖ®³õ£¬²¢·¢ÐÔÖ§³Ö¾ÍÊÇËüµÄÒ»¸öÌØÐÔ£¬Ï̺߳Íͬ²½µÄʵÏÖΪËüÌṩÁ˳¬Ô½ÆäËû¾ºÕùÓïÑÔµÄÓÅÊÆ¡£Scala »ùÓÚ Java ²¢ÔÚ JVM ÉÏÔËÐУ¬Äܹ»Ö±½Ó·ÃÎÊËùÓÐ Java ÔËÐÐʱ£¨°üÀ¨ËùÓв¢·¢ÐÔÖ§³Ö£©¡£ËùÒÔÔÚ·ÖÎö Scala ÌØÐÔ֮ǰ£¬ÎÒÊ×ÏÈ»á¿ìËٻعËһϠJava ÓïÑÔÒѾ­ÌṩµÄ¹¦ÄÜ¡£

Java Ï̻߳ù´¡

ÔÚ Java ±à³Ì¹ý³ÌÖд´½¨ºÍʹÓÃÏ̷߳dz£ÈÝÒס£ËüÃÇÓÉ java.lang.Thread Àà±íʾ£¬Ïß³ÌÒªÖ´ÐеĴúÂëΪ java.lang.Runnable ʵÀýµÄÐÎʽ¡£Èç¹ûÐèÒªµÄ»°£¬¿ÉÒÔÔÚÓ¦ÓóÌÐòÖд´½¨´óÁ¿Ị̈߳¬ÄúÉõÖÁ¿ÉÒÔ´´½¨Êýǧ¸öÏ̡߳£ÔÚÓжà¸öºËÐÄʱ£¬JVM ʹÓÃËüÃÇÀ´²¢·¢Ö´Ðжà¸öỊ̈߳»³¬³öºËÐÄÊýÁ¿µÄÏ̻߳ṲÏíÕâЩºËÐÄ¡£

Ï̲߳Ù×÷µÄЭµ÷ÄÑÒÔÈÃÈËÀí½â¡£Ö»Òª´Ó³ÌÐòµÄ½Ç¶ÈÈÃËùÓÐÄÚÈݱ£³ÖÒ»Ö£¬Java ±àÒëÆ÷ºÍ JVM ¾Í²»»á¶ÔÄú´úÂëÖеIJÙ×÷ÖØÐÂÅÅÐò£¬ÕâʹµÃÎÊÌâ±äµÃ¸ü¼Ó¸´ÔÓ¡£ÀýÈ磺Èç¹ûÁ½¸öÏà¼Ó²Ù×÷ʹÓÃÁ˲»Í¬µÄ±äÁ¿£¬±àÒëÆ÷»ò JVM ¿ÉÒÔ°²×°ÓëÖ¸¶¨µÄ˳ÐòÏà·´µÄ˳ÐòÖ´ÐÐÕâЩ²Ù×÷£¬Ö»Òª³ÌÐò²»ÔÚÁ½¸ö²Ù×÷¶¼Íê³É֮ǰʹÓÃÁ½¸ö±äÁ¿µÄ×ÜÊý¡£ÕâÖÖÖØÐÂÅÅÐò²Ù×÷µÄÁé»îÐÔÓÐÖúÓÚÌá¸ß Java ÐÔÄÜ£¬µ«Ò»ÖÂÐÔÖ»±»ÔÊÐíÓ¦ÓÃÔÚµ¥¸öÏß³ÌÖС£Ó²¼þÒ²ÓпÉÄÜ´øÀ´Ïß³ÌÎÊÌâ¡£ÏÖ´úϵͳʹÓÃÁ˶àÖÖ»º´æÄÚ´æ¼¶±ð£¬Ò»°ãÀ´½²£¬²»ÊÇϵͳÖеÄËùÓкËÐͼÄÜͬÑù¿´µ½ÕâЩ»º´æ¡£µ±Ä³¸öºËÐÄÐÞ¸ÄÄÚ´æÖеÄÒ»¸öֵʱ£¬ÆäËûºËÐÄ¿ÉÄܲ»»áÁ¢¼´¿´µ½´Ë¸ü¸Ä¡£

ÓÉÓÚÕâЩÎÊÌ⣬ÔÚÒ»¸öÏß³ÌʹÓÃÁíÒ»¸öÏß³ÌÐ޸ĵÄÊý¾Ýʱ£¬Äú±ØÐëÏÔʽµØ¿ØÖÆÏ߳̽»»¥·½Ê½¡£Java ʹÓÃÁËÌØÊâµÄ²Ù×÷À´ÌṩÕâÖÖ¿ØÖÆ£¬ÔÚ²»Í¬Ï߳̿´µ½µÄÊý¾ÝÊÓͼÖн¨Á¢Ë³Ðò¡£»ù±¾²Ù×÷ÊÇ£¬Ïß³ÌʹÓà synchronized ¹Ø¼ü×ÖÀ´·ÃÎÊÒ»¸ö¶ÔÏó¡£µ±Ä³¸öÏß³ÌÔÚÒ»¸ö¶ÔÏóÉϱ£³Öͬ²½Ê±£¬¸ÃÏ߳̽«»á»ñµÃ´Ë¶ÔÏóËù¶ÀÓеÄÒ»¸öËøµÄ¶ÀÕ¼·ÃÎÊ¡£Èç¹ûÁíÒ»¸öÏß³ÌÒѳÖÓиÃËø£¬µÈ´ý»ñÈ¡¸ÃËøµÄÏ̱߳ØÐëµÈ´ý£¬»òÕß±»×èÈû£¬Ö±µ½¸ÃËø±»ÊÍ·Å¡£µ±¸ÃÏß³ÌÔÚÒ»¸ö synchronized ´úÂë¿éÄÚ»Ö¸´Ö´ÐÐʱ£¬Java »á±£Ö¤¸ÃÏ߳̿ÉÒÔ ¡°¿´µ½ÁË¡± ÒÔǰ³ÖÓÐͬһ¸öËøµÄÆäËûÏß³ÌдÈëµÄËùÓÐÊý¾Ý£¬µ«Ö»ÊÇÕâЩÏß³Ìͨ¹ýÀ뿪×Ô¼ºµÄ synchronized ËøÀ´ÊͷŸÃËøÖ®Ç°Ð´ÈëµÄÊý¾Ý¡£ÕâÖÖ±£Ö¤¼ÈÊÊÓÃÓÚ±àÒëÆ÷»ò JVM ËùÖ´ÐеIJÙ×÷µÄÖØÐÂÅÅÐò£¬Ò²ÊÊÓÃÓÚÓ²¼þÄڴ滺´æ¡£Ò»¸ö synchronized ¿éµÄÄÚ²¿ÊÇÄú´úÂëÖеÄÒ»¸öÎȶ¨ÐԹµº£¬ÆäÖеÄÏ߳̿ÉÒÀ´Î°²È«µØÖ´ÐС¢½»»¥ºÍ¹²ÏíÐÅÏ¢¡£

ÔÚ±äÁ¿ÉÏ¶Ô volatile ¹Ø¼ü×ÖµÄʹÓã¬ÎªÏ̼߳äµÄ°²È«½»»¥ÌṩÁËÒ»ÖÖÉÔ΢½ÏÈõµÄÐÎʽ¡£synchronized ¹Ø¼ü×Ö¿ÉÈ·±£ÔÚÄú»ñÈ¡¸ÃËøÊ±¿ÉÒÔ¿´µ½ÆäËûÏ̵߳Ĵ洢£¬¶øÇÒÔÚÄúÖ®ºó£¬»ñÈ¡¸ÃËøµÄÆäËûÏß³ÌÒ²»á¿´µ½ÄúµÄ´æ´¢¡£volatile ¹Ø¼ü×Ö½«ÕâÒ»±£Ö¤·Ö½âΪÁ½¸ö²»Í¬µÄ²¿·Ö¡£Èç¹ûÒ»¸öÏß³ÌÏò volatile ±äÁ¿Ð´ÈëÊý¾Ý£¬ÄÇôÊ×ÏȽ«»á²Á³ýËüÔÚÕâ֮ǰдÈëµÄÊý¾Ý¡£Èç¹ûij¸öÏ̶߳ÁÈ¡¸Ã±äÁ¿£¬ÄÇô¸ÃÏ̲߳»½ö»á¿´µ½Ð´Èë¸Ã±äÁ¿µÄÖµ£¬»¹»á¿´µ½Ð´ÈëµÄÏß³ÌËùдÈëµÄÆäËûËùÓÐÖµ¡£ËùÒÔ¶Áȡһ¸ö volatile ±äÁ¿»áÌṩÓëÊäÈë Ò»¸ö synchronized ¿éÏàͬµÄÄÚ´æ±£Ö¤£¬¶øÇÒдÈëÒ»¸ö volatile ±äÁ¿»áÌṩÓëÀ뿪 Ò»¸ö synchronized ¿éÏàͬµÄÄÚ´æ±£Ö¤¡£µ«¶þÕßÖ®¼äÓкܴóµÄ²î±ð£ºvolatile ±äÁ¿µÄ¶ÁÈ¡»òдÈë¾ø²»»áÊÜ×èÈû¡£

³éÏó Java ²¢·¢ÐÔ

ͬ²½ºÜÓÐÓ㬶øÇÒÐí¶à¶àÏß³ÌÓ¦ÓóÌÐò¶¼ÊÇÔÚ Java ÖнöʹÓûù±¾µÄ synchronized ¿é¿ª·¢³öÀ´µÄ¡£µ«Ð­µ÷Ï߳̿ÉÄܺÜÂé·³£¬ÓÈÆäÊÇÔÚ´¦ÀíÐí¶àÏ̺߳ÍÐí¶à¿éµÄʱºò¡£È·±£Ï߳̽öÔÚ°²È«µÄ·½Ê½Ï½»»¥²¢ ±ÜÃâDZÔÚµÄËÀËø£¨Á½¸ö»ò¸ü¶àÏ̵߳ȴý¶Ô·½ÊÍ·ÅËøÖ®ºó²ÅÄܼÌÐøÖ´ÐУ©£¬ÕâºÜÀ§ÄÑ¡£Ö§³Ö²¢·¢ÐÔ¶ø²»Ö±½Ó´¦ÀíÏ̺߳ÍËøµÄ³éÏó£¬ÕâΪ¿ª·¢ÈËÔ±ÌṩÁË´¦Àí³£¼ûÓÃÀýµÄ¸üºÃ·½·¨¡£

java.util.concurrent ·Ö²ã½á¹¹°üº¬Ò»Ð©¼¯ºÏ±äÐΣ¬ËüÃÇÖ§³Ö²¢·¢·ÃÎÊ¡¢Õë¶ÔÔ­×Ó²Ù×÷µÄ°ü×°Æ÷À࣬ÒÔ¼°Í¬²½Ô­Óï¡£ÕâЩÀàÖеÄÐí¶à¶¼ÊÇΪ֧³Ö·Ç×èÈû·ÃÎʶøÉè¼ÆµÄ£¬Õâ±ÜÃâÁËËÀËøµÄÎÊÌ⣬¶øÇÒʵÏÖÁ˸ü¸ßЧµÄÏ̡߳£ÕâЩÀàʹµÃ¶¨ÒåºÍ¿ØÖÆÏß³ÌÖ®¼äµÄ½»»¥±äµÃ¸üÈÝÒ×£¬µ«ËûÃÇÈÔÈ»ÃæÁÙ×Å»ù±¾Ïß³ÌÄ£Ð͵ÄһЩ¸´ÔÓÐÔ¡£

java.util.concurrent °üÖеÄÒ»¶Ô³éÏó£¬Ö§³Ö²ÉÓÃÒ»ÖÖ¸ü¼Ó·ÖÀëµÄ·½·¨À´´¦Àí²¢·¢ÐÔ£ºFuture<T> ½Ó¿Ú¡¢Executor ºÍ ExecutorService ½Ó¿Ú¡£ÕâЩÏà¹ØµÄ½Ó¿Ú½ø¶ø³ÉΪÁË¶Ô Java ²¢·¢ÐÔÖ§³ÖµÄÐí¶à Scala ºÍ Akka À©Õ¹µÄ»ù´¡£¬ËùÒÔ¸üÏêϸµØÁ˽âÕâЩ½Ó¿ÚºÍËüÃǵÄʵÏÖÊÇÖµµÃµÄ¡£
Future<T> ÊÇÒ»¸ö T ÀàÐ͵ÄÖµµÄ³ÖÓÐÕߣ¬µ«Ææ¹ÖµÄÊǸÃÖµÒ»°ãÔÚ´´½¨ Future Ö®ºó²ÅÄÜʹÓá£ÕýÈ·Ö´ÐÐÒ»¸öͬ²½²Ù×÷ºó£¬²Å»á»ñµÃ¸ÃÖµ¡£ÊÕµ½ Future µÄÏ߳̿ɵ÷Ó÷½·¨À´£º

1.²é¿´¸ÃÖµÊÇ·ñ¿ÉÓÃ

2.µÈ´ý¸ÃÖµ±äΪ¿ÉÓÃ

3.ÔÚ¸ÃÖµ¿ÉÓÃʱ»ñÈ¡Ëü

4.Èç¹û²»ÔÙÐèÒª¸ÃÖµ£¬ÔòÈ¡Ïû¸Ã²Ù×÷

Future µÄ¾ßÌåʵÏֽṹ֧³Ö´¦ÀíÒì²½²Ù×÷µÄ²»Í¬·½Ê½¡£

Executor ÊÇÒ»ÖÖÎ§ÈÆÄ³¸öÖ´ÐÐÈÎÎñµÄ¶«Î÷µÄ³éÏó¡£Õâ¸ö ¡°¶«Î÷¡± ×îÖÕ½«ÊÇÒ»¸öỊ̈߳¬µ«¸Ã½Ó¿ÚÒþ²ØÁ˸ÃÏ̴߳¦ÀíÖ´ÐеÄϸ½Ú¡£Executor ±¾ÉíµÄÊÊÓÃÐÔÓÐÏÞ£¬ExecutorService ×Ó½Ó¿ÚÌṩÁ˹ÜÀíÖÕÖ¹µÄÀ©Õ¹·½·¨£¬²¢ÎªÈÎÎñµÄ½á¹ûÉú³ÉÁË Future¡£Executor µÄËùÓбê׼ʵÏÖ»¹»áʵÏÖ ExecutorService£¬ËùÒÔʵ¼ÊÉÏ£¬Äú¿ÉÒÔºöÂÔ¸ù½Ó¿Ú¡£

Ïß³ÌÊÇÏà¶ÔÖØÁ¿¼¶µÄ×ÊÔ´£¬¶øÇÒÓë·ÖÅä²¢¶ªÆúËüÃÇÏà±È£¬ÖØÓÃËüÃǸüÓÐÒâÒå¡£ExecutorService ¼ò»¯ÁËÏ̼߳äµÄ¹¤×÷¹²Ïí£¬»¹Ö§³Ö×Ô¶¯ÖØÓÃỊ̈߳¬ÊµÏÖÁ˸üÇáËɵıà³ÌºÍ¸ü¸ßµÄÐÔÄÜ¡£ExecutorService µÄ ThreadPoolExecutor ʵÏÖ¹ÜÀí×ÅÒ»¸öÖ´ÐÐÈÎÎñµÄÏ̳߳ء£

Ó¦Óà Java ²¢·¢ÐÔ

²¢·¢ÐÔµÄʵ¼ÊÓ¦Ó󣳣ɿ¼°µ½ÐèÒªÓëÄúµÄÖ÷Òª´¦ÀíÂß¼­¶ÀÁ¢µÄÍⲿ½»»¥µÄÈÎÎñ£¨ÓëÓû§¡¢´æ´¢»òÆäËûϵͳµÄ½»»¥£©¡£ÕâÀàÓ¦ÓúÜÄÑŨËõΪһ¸ö¼òµ¥µÄʾÀý£¬ËùÒÔÔÚÑÝʾ²¢·¢ÐÔµÄʱºò£¬ÈËÃÇͨ³£»áʹÓüòµ¥µÄ¼ÆËãÃܼ¯ÐÍÈÎÎñ£¬±ÈÈçÊýѧ¼ÆËã»òÅÅÐò¡£ÎÒ½«Ê¹ÓÃÒ»¸öÀàËÆµÄʾÀý¡£

ÈÎÎñÊÇÕÒµ½ÀëÒ»¸öδ֪µÄÊäÈë×î½üµÄÒÑÖªµ¥´Ê£¬ÆäÖеÄ×î½ü Êǰ´ÕÕLevenshtein ¾àÀë À´¶¨ÒåµÄ£º½«ÊäÈëת»»ÎªÒÑÖªµÄµ¥´ÊËùÐèµÄ×îÉÙµÄ×Ö·ûÔö¼Ó¡¢É¾³ý»ò¸ü¸Ä´ÎÊý¡£ÎÒʹÓõĴúÂë»ùÓÚ Wikipedia É쵀 Levenshtein ¾àÀë ÎÄÕÂÖеÄÒ»¸öʾÀý£¬¸ÃʾÀý¼ÆËãÁËÿ¸öÒÑÖªµ¥´ÊµÄ Levenshtein ¾àÀ룬²¢·µ»Ø×î¼ÑÆ¥ÅäÖµ£¨»òÕßÈç¹û¶à¸öÒÑÖªµÄµ¥´ÊÓµÓÐÏàͬµÄ¾àÀ룬ÄÇô·µ»Ø½á¹ûÊDz»È·¶¨µÄ£©¡£

Çåµ¥ 1 ¸ø³öÁ˼ÆËã Levenshtein ¾àÀëµÄ Java ´úÂë¡£¸Ã¼ÆËãÉú³ÉÒ»¸ö¾ØÕ󣬽«ÐкÍÁÐÓëÁ½¸ö¶Ô±ÈµÄÎı¾µÄ´óС½øÐÐÆ¥Å䣬ÔÚÿ¸öά¶ÈÉÏ¼Ó 1¡£ÎªÁËÌá¸ßЧÂÊ£¬´ËʵÏÖʹÓÃÁËÒ»¶Ô´óСÓëÄ¿±êÎı¾ÏàͬµÄÊý×éÀ´±íʾ¾ØÕóµÄÁ¬ÐøÐУ¬½«ÕâЩÊý×é°ü×°ÔÚÿ¸öÑ­»·ÖУ¬ÒòΪÎÒÖ»ÐèÒªÉÏÒ»ÐеÄÖµ¾Í¿ÉÒÔ¼ÆËãÏÂÒ»ÐС£

Çåµ¥ 1. Java ÖÐµÄ Levenshtein ¾àÀë¼ÆËã

/**
* Calculate edit distance from targetText to known word.
*
* @param word known word
* @param v0 int array of length targetText.length() + 1
* @param v1 int array of length targetText.length() + 1
* @return distance
*/
private int editDistance(String word, int[] v0, int[] v1) {

// initialize v0 (prior row of distances) as edit distance for empty 'word'
for (int i = 0; i < v0.length; i++) {
v0[i] = i;
}

// calculate updated v0 (current row distances) from the previous row v0
for (int i = 0; i < word.length(); i++) {

// first element of v1 = delete (i+1) chars from target to match empty 'word'
v1[0] = i + 1;

// use formula to fill in the rest of the row
for (int j = 0; j < targetText.length(); j++) {
int cost = (word.charAt(i) == targetText.charAt(j)) ? 0 : 1;
v1[j + 1] = minimum(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost);
}

// swap v1 (current row) and v0 (previous row) for next iteration
int[] hold = v0;
v0 = v1;
v1 = hold;
}

// return final value representing best edit distance
return v0[targetText.length()];
}

Èç¹ûÓдóÁ¿ÒÑÖª´Ê»ãÒªÓëδ֪µÄÊäÈë½øÐбȽϣ¬¶øÇÒÄúÔÚÒ»¸ö¶àºËϵͳÉÏÔËÐУ¬ÄÇôÄú¿ÉÒÔʹÓò¢·¢ÐÔÀ´¼ÓËÙ´¦Àí£º½«ÒÑÖªµ¥´ÊµÄ¼¯ºÏ·Ö½âΪ¶à¸ö¿é£¬½«Ã¿¸ö¿é×÷Ϊһ¸ö¶ÀÁ¢ÈÎÎñÀ´´¦Àí¡£Í¨¹ý¸ü¸Äÿ¸ö¿éÖеĵ¥´ÊÊýÁ¿£¬Äú¿ÉÒÔÇáËɵظü¸ÄÈÎÎñ·Ö½âµÄÁ£¶È£¬´Ó¶øÁ˽âËüÃǶÔ×ÜÌåÐÔÄܵÄÓ°Ïì¡£Çåµ¥ 2 ¸ø³öÁË·Ö¿é¼ÆËãµÄ Java ´úÂ룬ժ×Ô Ê¾Àý´úÂë ÖÐµÄ ThreadPoolDistance Àà¡£Çåµ¥ 2 ʹÓÃÒ»¸ö±ê×¼µÄ ExecutorService£¬½«Ïß³ÌÊýÁ¿ÉèÖÃΪ¿ÉÓõĴ¦ÀíÆ÷ÊýÁ¿¡£

Çåµ¥ 2. ÔÚ Java ÖÐͨ¹ý¶à¸öÏß³ÌÀ´Ö´ÐзֿéµÄ¾àÀë¼ÆËã

private final ExecutorService threadPool;
private final String[] knownWords;
private final int blockSize;

public ThreadPoolDistance(String[] words, int block) {
threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
knownWords = words;
blockSize = block;
}

public DistancePair bestMatch(String target) {

// build a list of tasks for matching to ranges of known words
List<DistanceTask> tasks = new ArrayList<DistanceTask>();

int size = 0;
for (int base = 0; base < knownWords.length; base += size) {
size = Math.min(blockSize, knownWords.length - base);
tasks.add(new DistanceTask(target, base, size));
}
DistancePair best;
try {

// pass the list of tasks to the executor, getting back list of futures
List<Future<DistancePair>> results = threadPool.invokeAll(tasks);

// find the best result, waiting for each future to complete
best = DistancePair.WORST_CASE;
for (Future<DistancePair> future: results) {
DistancePair result = future.get();
best = DistancePair.best(best, result);
}

} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
return best;
}

/**
* Shortest distance task implementation using Callable.
*/
public class DistanceTask implements Callable<DistancePair>
{
private final String targetText;
private final int startOffset;
private final int compareCount;

public DistanceTask(String target, int offset, int count) {
targetText = target;
startOffset = offset;
compareCount = count;
}

private int editDistance(String word, int[] v0, int[] v1) {
...
}

/* (non-Javadoc)
* @see java.util.concurrent.Callable#call()
*/
@Override
public DistancePair call() throws Exception {

// directly compare distances for comparison words in range
int[] v0 = new int[targetText.length() + 1];
int[] v1 = new int[targetText.length() + 1];
int bestIndex = -1;
int bestDistance = Integer.MAX_VALUE;
boolean single = false;
for (int i = 0; i < compareCount; i++) {
int distance = editDistance(knownWords[i + startOffset], v0, v1);
if (bestDistance > distance) {
bestDistance = distance;
bestIndex = i + startOffset;
single = true;
} else if (bestDistance == distance) {
single = false;
}
}
return single ? new DistancePair(bestDistance, knownWords[bestIndex]) :
new DistancePair(bestDistance);
}
}

Çåµ¥ 2 ÖÐµÄ bestMatch() ·½·¨¹¹ÔìÒ»¸ö DistanceTask ¾àÀëÁÐ±í£¬È»ºó½«¸ÃÁÐ±í´«µÝ¸ø ExecutorService¡£ÕâÖÖ¶Ô ExecutorService µÄµ÷ÓÃÐÎʽ½«»á½ÓÊÜÒ»¸ö Collection<? extends Callable<T>> ÀàÐ͵IJÎÊý£¬¸Ã²ÎÊý±íʾҪִÐеÄÈÎÎñ¡£¸Ãµ÷Ó÷µ»ØÒ»¸ö Future<T> ÁÐ±í£¬ÓÃËüÀ´±íʾִÐеĽá¹û¡£ExecutorService ʹÓÃÔÚÿ¸öÈÎÎñÉϵ÷Óà call() ·½·¨Ëù·µ»ØµÄÖµ£¬Òì²½ÌîдÕâЩ½á¹û¡£ÔÚ±¾ÀýÖУ¬T ÀàÐÍΪ DistancePair¡ª Ò»¸ö±íʾ¾àÀëºÍÆ¥ÅäµÄµ¥´ÊµÄ¼òµ¥µÄÖµ¶ÔÏ󣬻òÕßÔÚûÓÐÕÒµ½Î©Ò»Æ¥Åäֵʱ½ü±íʾ¾àÀë¡£

bestMatch() ·½·¨ÖÐÖ´ÐеÄԭʼÏß³ÌÒÀ´ÎµÈ´ýÿ¸ö Future Íê³É£¬ÀÛ»ý×î¼ÑµÄ½á¹û²¢ÔÚÍê³Éʱ·µ»ØËü¡£Í¨¹ý¶à¸öÏß³ÌÀ´´¦Àí DistanceTask µÄÖ´ÐУ¬Ô­Ê¼Ïß³ÌÖ»ÐèµÈ´ýһС²¿·Ö½á¹û¡£Ê£Óà½á¹û¿ÉÓëԭʼÏ̵߳ȴýµÄ½á¹û²¢·¢µØÍê³É¡£

²¢·¢ÐÔÐÔÄÜ

Òª³ä·ÖÀûÓÃϵͳÉÏ¿ÉÓõĴ¦ÀíÆ÷ÊýÁ¿£¬±ØÐëΪ ExecutorService ÅäÖÃÖÁÉÙÓë´¦ÀíÆ÷Ò»Ñù¶àµÄÏ̡߳£Äú»¹±ØÐ뽫ÖÁÉÙÓë´¦ÀíÆ÷Ò»Ñù¶àµÄÈÎÎñ´«µÝ¸ø ExecutorService À´Ö´ÐС£Êµ¼ÊÉÏ£¬Äú»òÐíÏ£ÍûÓµÓбȴ¦ÀíÆ÷¶àµÃ¶àµÄÈÎÎñ£¬ÒÔʵÏÖ×î¼ÑµÄÐÔÄÜ¡£ÕâÑù£¬´¦ÀíÆ÷¾Í»á·±Ã¦µØ´¦ÀíÒ»¸ö½ÓÒ»¸öµÄÈÎÎñ£¬½üÔÚ×îºó²Å¿ÕÏÐÏÂÀ´¡£µ«ÊÇÒòÎªÉæ¼°µ½¿ªÏú£¨ÔÚ´´½¨ÈÎÎñºÍ future µÄ¹ý³ÌÖУ¬ÔÚÈÎÎñÖ®¼äÇл»Ï̵߳Ĺý³ÌÖУ¬ÒÔ¼°×îÖÕ·µ»ØÈÎÎñµÄ½á¹ûʱ£©£¬Äú±ØÐë±£³ÖÈÎÎñ×ã¹»´ó£¬ÒԱ㿪ÏúÊǰ´±ÈÀý¼õСµÄ¡£

ͼ 1 չʾÁËÎÒÔÚʹÓà Oracle µÄ Java 7 for 64-bit Linux? µÄËÄºË AMD ϵͳÉÏÔËÐвâÊÔ´úÂëʱ²âÁ¿µÄ²»Í¬ÈÎÎñÊýÁ¿µÄÐÔÄÜ¡£Ã¿¸öÊäÈëµ¥´ÊÒÀ´ÎÓë 12,564 ¸öÒÑÖªµ¥´ÊÏà±È½Ï£¬Ã¿¸öÈÎÎñÔÚÒ»¶¨·¶Î§µÄÒÑÖªµ¥´ÊÖÐÕÒµ½×î¼ÑµÄÆ¥ÅäÖµ¡£È«²¿ 933 ¸öƴд´íÎóµÄÊäÈëµ¥´Ê»áÖØ¸´ÔËÐУ¬Ã¿ÂÖÔËÐÐÖ®¼ä»áÔÝͣƬ¿Ì¹© JVM ´¦Àí£¬¸ÃͼÖÐʹÓÃÁË 10 ÂÖÔËÐкóµÄ×î¼Ñʱ¼ä¡£´Óͼ 1 ÖпÉÒÔ¿´³ö£¬Ã¿ÃëµÄÊäÈëµ¥´ÊÐÔÄÜÔÚºÏÀíµÄ¿é´óС·¶Î§ÄÚ£¨»ù±¾À´½²£¬´Ó 256 µ½´óÓÚ 1,024£©¿´ÆðÀ´ÊǺÏÀíµÄ£¬Ö»ÓÐÔÚÈÎÎñ±äµÃ·Ç³£Ð¡»ò·Ç³£´óʱ£¬ÐÔÄܲŻἫËÙϽµ¡£¶ÔÓÚ¿é´óС 16,384£¬×îºóµÄÖµ½ü´´½¨ÁËÒ»¸öÈÎÎñ£¬ËùÒÔÏÔʾÁ˵¥Ïß³ÌÐÔÄÜ¡£

ͼ 1. ThreadPoolDistance ÐÔÄÜ

Fork-Join

Java 7 ÒýÈëÁË ExecutorService µÄÁíÒ»ÖÖʵÏÖ£ºForkJoinPool Àà¡£ForkJoinPool ÊÇΪ¸ßЧ´¦Àí¿É·´¸´·Ö½âΪ×ÓÈÎÎñµÄÈÎÎñ¶øÉè¼ÆµÄ£¬ËüʹÓà RecursiveAction ÀࣨÔÚÈÎÎñδÉú³É½á¹ûʱ£©»ò RecursiveTask<T> ÀࣨÔÚÈÎÎñ¾ßÓÐÒ»¸ö T ÀàÐ͵Ľá¹ûʱ£©À´´¦ÀíÈÎÎñ¡£RecursiveTask<T> ÌṩÁËÒ»Öֺϲ¢×ÓÈÎÎñ½á¹ûµÄ±ã½Ý·½Ê½£¬ÈçÇåµ¥ 3 Ëùʾ¡£

Çåµ¥ 3. RecursiveTask<DistancePair> ʾÀý

private ForkJoinPool threadPool = new ForkJoinPool();

private final String[] knownWords;

private final int blockSize;

public ForkJoinDistance(String[] words, int block) {
knownWords = words;
blockSize = block;
}

public DistancePair bestMatch(String target) {
return threadPool.invoke(new DistanceTask(target, 0, knownWords.length, knownWords));
}

/**
* Shortest distance task implementation using RecursiveTask.
*/
public class DistanceTask extends RecursiveTask<DistancePair>
{
private final String compareText;
private final int startOffset;
private final int compareCount;
private final String[] matchWords;

public DistanceTask(String from, int offset, int count, String[] words) {
compareText = from;
startOffset = offset;
compareCount = count;
matchWords = words;
}

private int editDistance(int index, int[] v0, int[] v1) {
...
}

/* (non-Javadoc)
* @see java.util.concurrent.RecursiveTask#compute()
*/
@Override
protected DistancePair compute() {
if (compareCount > blockSize) {

// split range in half and find best result from bests in each half of range
int half = compareCount / 2;
DistanceTask t1 = new DistanceTask(compareText, startOffset, half, matchWords);
t1.fork();
DistanceTask t2 = new DistanceTask(compareText, startOffset + half,
compareCount - half, matchWords);
DistancePair p2 = t2.compute();
return DistancePair.best(p2, t1.join());
}

// directly compare distances for comparison words in range
int[] v0 = new int[compareText.length() + 1];
int[] v1 = new int[compareText.length() + 1];
int bestIndex = -1;
int bestDistance = Integer.MAX_VALUE;
boolean single = false;
for (int i = 0; i < compareCount; i++) {
int distance = editDistance(i + startOffset, v0, v1);
if (bestDistance > distance) {
bestDistance = distance;
bestIndex = i + startOffset;
single = true;
} else if (bestDistance == distance) {
single = false;
}
}
return single ? new DistancePair(bestDistance, knownWords[bestIndex]) :
new DistancePair(bestDistance);
}
}

ͼ 2 ÏÔʾÁËÇåµ¥ 3 ÖÐµÄ ForkJoin ´úÂëÓë Çåµ¥ 2 ÖÐµÄ ThreadPool ´úÂëµÄÐÔÄܶԱȡ£ForkJoin ´úÂëÔÚËùÓпé´óСÖÐÎȶ¨µÃ¶à£¬½öÔÚÄúÖ»Óе¥¸ö¿é£¨Òâζ×ÅÖ´ÐÐÊǵ¥Ï̵߳ģ©Ê±ÐÔÄÜ»áÏÔÖøÏ½µ¡£±ê×¼µÄ ThreadPool ´úÂë½öÔÚ¿é´óСΪ 256 ºÍ 1,024 ʱ»á±íÏÖ³ö¸üºÃµÄÐÔÄÜ¡£

ͼ 2. ThreadPoolDistance Óë ForkJoinDistance µÄÐÔÄܶԱÈ

ÕâЩ½á¹û±íÃ÷£¬Èç¹û¿Éµ÷½ÚÓ¦ÓóÌÐòÖеÄÈÎÎñ´óСÀ´ÊµÏÖ×î¼ÑµÄÐÔÄÜ£¬ÄÇôʹÓñê×¼ ThreadPool ±È ForkJoin ¸üºÃ¡£µ«Çë×¢Ò⣬ThreadPool µÄ ¡°×î¼ÑÐÔÄܵ㡱 È¡¾öÓÚ¾ßÌåÈÎÎñ¡¢¿ÉÓô¦ÀíÆ÷ÊýÁ¿ÒÔ¼°ÄúϵͳµÄÆäËûÒòËØ¡£Ò»°ã¶øÑÔ£¬ForkJoin ÒÔ×îСµÄµ÷ÓÅÐèÇó´øÀ´ÁËÓÅÐãµÄÐÔÄÜ£¬ËùÒÔ×îºÃ¾¡¿ÉÄܵØÊ¹ÓÃËü¡£

Scala ²¢·¢ÐÔ»ù´¡

Scala ͨ¹ýÐí¶à·½Ê½À©Õ¹ÁË Java ±à³ÌÓïÑÔºÍÔËÐÐʱ£¬ÆäÖаüÀ¨Ìí¼Ó¸ü¶à¡¢¸üÇáËɵĴ¦Àí²¢·¢ÐԵķ½Ê½¡£¶ÔÓÚ³õѧÕß¶øÑÔ£¬Future<T> µÄ Scala °æ±¾±È Java °æ±¾Áé»îµÃ¶à¡£Äú¿ÉÒÔÖ±½Ó´Ó´úÂë¿éÖд´½¨ future£¬¿ÉÏò future ¸½¼Ó»Øµ÷À´´¦ÀíÕâЩ future µÄÍê³É¡£Çåµ¥ 4 ÏÔʾÁË Scala future µÄһЩʹÓÃʾÀý¡£¸Ã´úÂëÊ×Ïȶ¨ÒåÁË futureInt() ·½·¨£¬ÒԱ㰴ÐèÌṩ Future<Int>£¬È»ºóͨ¹ýÈýÖÖ²»Í¬µÄ·½Ê½À´Ê¹Óà future¡£

Çåµ¥ 4. Scala Future<T> ʾÀý´úÂë

import ExecutionContext.Implicits.global

val lastInteger = new AtomicInteger
def futureInt() = future {
Thread sleep 2000
lastInteger incrementAndGet
}

// use callbacks for completion of futures
val a1 = futureInt
val a2 = futureInt
a1.onSuccess {
case i1 => {
a2.onSuccess {
case i2 => println("Sum of values is " + (i1 + i2))
}
}
}
Thread sleep 3000

// use for construct to extract values when futures complete
val b1 = futureInt
val b2 = futureInt
for (i1 <- b1; i2 <- b2) yield println("Sum of values is " + (i1 + i2))
Thread sleep 3000

// wait directly for completion of futures
val c1 = futureInt
val c2 = futureInt
println("Sum of values is " + (Await.result(c1, Duration.Inf) +
Await.result(c2, Duration.Inf)))

Çåµ¥ 4 ÖеĵÚÒ»¸öʾÀý½«»Øµ÷±Õ°ü¸½¼Óµ½Ò»¶Ô future ÉÏ£¬ÒÔ±ãÔÚÁ½¸ö future ¶¼Íê³Éʱ£¬½«Á½¸ö½á¹ûÖµµÄºÍ´òÓ¡µ½¿ØÖÆÌ¨ÉÏ¡£»Øµ÷Êǰ´ÕÕ´´½¨ËüÃǵÄ˳ÐòÖ±½ÓǶÌ×ÔÚ future ÉÏ£¬µ«ÊÇ£¬¼´Ê¹¸ü¸Ä˳Ðò£¬ËüÃÇҲͬÑùÓÐЧ¡£Èç¹ûÔÚÄú¸½¼Ó»Øµ÷ʱ future ÒÑÍê³É£¬¸Ã»Øµ÷ÈÔ»áÔËÐУ¬µ«ÎÞ·¨±£Ö¤Ëü»áÁ¢¼´ÔËÐС£Ô­Ê¼Ö´ÐÐÏ̻߳áÔÚ Thread sleep 3000 ÐÐÉÏÔÝÍ££¬ÒÔ±ãÔÚ½øÈëÏÂÒ»¸öʾÀý֮ǰÍê³É future¡£

µÚ¶þ¸öʾÀýÑÝʾÁËʹÓà Scala for comprehension ´Ó future ÖÐÒì²½Ìáȡֵ£¬È»ºóÖ±½ÓÔÚ±í´ïʽÖÐʹÓÃËüÃÇ¡£for comprehension ÊÇÒ»ÖÖ Scala ½á¹¹£¬¿ÉÓÃÓÚ¼ò½àµØ±í´ï¸´ÔӵIJÙ×÷×éºÏ£¨map¡¢filter¡¢flatMap ºÍ foreach£©¡£ËüÒ»°ãÓë¸÷ÖÖÐÎʽµÄ¼¯ºÏ½áºÏʹÓ㬵« Scala future ʵÏÖÁËÏàͬµÄµ¥Öµ·½·¨À´·ÃÎʼ¯ºÏÖµ¡£ËùÒÔ¿ÉÒÔʹÓà future ×÷ΪһÖÖÌØÊâµÄ¼¯ºÏ£¬Ò»ÖÖ°üº¬×î¶àÒ»¸öÖµ£¨¿ÉÄÜÉõÖÁÔÚδÀ´Ä³¸öʱ¿Ì֮ǰ֮ºó²Å°üº¬¸ÃÖµ£©µÄ¼¯ºÏ¡£ÔÚÕâÖÖÇé¿öÏ£¬for Óï¾äÒªÇó»ñÈ¡ future µÄ½á¹û£¬²¢ÔÚ±í´ïʽÖÐʹÓÃÕâЩ½á¹ûÖµ¡£ÔÚÄ»ºó£¬ÕâÖÖ¼¼Êõ»áÉú³ÉÓëµÚÒ»¸öʾÀýÍêÈ«ÏàͬµÄ´úÂ룬µ«ÒÔÏßÐÔ´úÂëµÄÐÎʽ±àдËü»áµÃµ½¸üÈÝÒ×Àí½âµÄ¸ü¼òµ¥µÄ±í´ïʽ¡£ºÍµÚÒ»¸öʾÀýÒ»Ñù£¬Ô­Ê¼Ö´ÐÐÏ̻߳áÔÝÍ££¬ÒÔ±ãÔÚ½øÈëÏÂÒ»¸öʾÀý֮ǰÍê³É future¡£

µÚÈý¸öʾÀýʹÓÃ×èÈûµÈ´ýÀ´»ñÈ¡ future µÄ½á¹û¡£ÕâÓë Java future µÄ¹¤×÷Ô­ÀíÏàͬ£¬µ«ÔÚ Scala ÖУ¬Ò»¸ö»ñÈ¡×î´óµÈ´ýʱ¼ä²ÎÊýµÄÌØÊâ Await.result() ·½·¨µ÷ÓûáÈÃ×èÈûµÈ´ý±äµÃ¸üΪÃ÷ÏÔ¡£

Çåµ¥ 4 ÖеĴúÂëûÓÐÏÔʽµØ½« future ´«µÝ¸ø ExecutorService »òµÈЧµÄ¶ÔÏó£¬ËùÒÔÈç¹ûûÓÐʹÓùý Scala£¬ÄÇôÄú¿ÉÄÜÏëÖªµÀ future ÄÚ²¿µÄ´úÂëÊÇÈçºÎÖ´Ðеġ£´ð°¸È¡¾öÓÚ Çåµ¥ 4 ÖÐ×îÉÏÃæÒ»ÐУºimport ExecutionContext.Implicits.global¡£Scala API ³£³£Îª´úÂë¿éÖÐÆµ·±ÖØÓõIJÎÊýʹÓà implicit Öµ¡£future { } ½á¹¹ÒªÇó ExecutionContext ÒÔÒþʽ²ÎÊýµÄÐÎʽÌṩ¡£Õâ¸ö ExecutionContext ÊÇ Java ExecutorService µÄÒ»¸ö Scala °ü×°Æ÷£¬ÒÔÏàͬ·½Ê½ÓÃÓÚʹÓÃÒ»¸ö»ò¶à¸öÍйÜÏß³ÌÀ´Ö´ÐÐÈÎÎñ¡£

³ýÁË future µÄÕâЩ»ù±¾²Ù×÷Ö®Í⣬Scala »¹ÌṩÁËÒ»ÖÖ·½Ê½½«Èκμ¯ºÏת»»ÎªÊ¹Óò¢Ðбà³ÌµÄ¼¯ºÏ¡£½«¼¯ºÏת»»Îª²¢Ðиñʽºó£¬ÄúÔÚ¼¯ºÏÉÏÖ´ÐеÄÈκαê×¼µÄ Scala ¼¯ºÏ²Ù×÷£¨±ÈÈç map¡¢filter »ò fold£©¶¼»á×Ô¶¯µØ¾¡¿ÉÄܲ¢ÐÐÍê³É¡££¨±¾ÎÄÉÔºó»áÔÚ Çåµ¥ 7 ÖÐÌṩһ¸öÏà¹ØÊ¾Àý£¬¸ÃʾÀýʹÓà Scala ²éÕÒÒ»¸öµ¥´ÊµÄ×î¼ÑÆ¥ÅäÖµ¡££©

´íÎó´¦Àí

Java ºÍ Scala ÖÐµÄ future ¶¼±ØÐë½â¾ö´íÎó´¦ÀíµÄÎÊÌâ¡£ÔÚ Java ÖУ¬½ØÖÁ Java 7£¬future ¿ÉÅ׳öÒ»¸ö ExecutionException ×÷Ϊ·µ»Ø½á¹ûµÄÌæ´ú·½°¸¡£Ó¦ÓóÌÐò¿ÉÕë¶Ô¾ßÌåµÄʧ°ÜÀàÐͶø¶¨Òå×Ô¼ºµÄ ExecutionException ×ÓÀ࣬»òÕß¿ÉÁ¬ËøÒì³£À´´«µÝÏêϸÐÅÏ¢£¬µ«ÕâÏÞÖÆÁËÁé»îÐÔ¡£

Scala future ÌṩÁ˸üÁé»îµÄ´íÎó´¦Àí¡£Äú¿ÉÒÔͨ¹ýÁ½ÖÖ·½Ê½Íê³É Scala future£º³É¹¦Ê±Ìṩһ¸ö½á¹ûÖµ£¨¼ÙÉèÒªÇóÒ»¸ö½á¹ûÖµ£©£¬»òÕßÔÚʧ°ÜʱÌṩһ¸ö¹ØÁªµÄ Throwable¡£ÄúÒ²¿ÉÒÔ²ÉÓöàÖÖ·½Ê½´¦Àí future µÄÍê³É¡£ÔÚ Çåµ¥ 4 ÖУ¬onSuccess ·½·¨ÓÃÓÚ¸½¼Ó»Øµ÷À´´¦Àí future µÄ³É¹¦Íê³É¡£Äú»¹¿ÉÒÔʹÓà onComplete À´´¦ÀíÈκÎÐÎʽµÄÍê³É£¨Ëü½«½á¹û»ò throwable °ü×°ÔÚÒ»¸ö Try ÖÐÀ´ÊÊÓ¦Á½ÖÖÇé¿ö£©£¬»òÕßʹÓà onFailure À´×¨ÃÅ´¦Àí´íÎó½á¹û¡£Scala future µÄÕâÖÖÁé»îÐÔÀ©Õ¹µ½ÁËÄú¿ÉÒÔʹÓà future Ö´ÐеÄËùÓвÙ×÷£¬ËùÒÔÄú¿ÉÒÔ½«´íÎó´¦ÀíÖ±½Ó¼¯³Éµ½´úÂëÖС£

Õâ¸ö Scala Future<T> »¹ÓÐÒ»¸ö½ôÃÜÏà¹ØµÄ Promise<T> Àà¡£future ÊÇÒ»¸ö½á¹ûµÄ³ÖÓÐÕߣ¬¸Ã½á¹ûÔÚij¸öʱ¿Ì¿ÉÄÜ¿ÉÓ㨻ò²»¿ÉÓà ¡ª ÎÞ·¨ÄÚÔÚµØÈ·±£Ò»¸ö future ½«Íê³É£©¡£future Íê³Éºó£¬½á¹ûÊǹ̶¨µÄ£¬²»»á·¢Éú¸Ä±ä¡£promise ÊÇÕâ¸öÏàͬÆõÔ¼µÄÁíÒ»¶Ë£º½á¹ûµÄÒ»¸öÒ»´ÎÐÔ¡¢¿É·ÖÅäµÄ³ÖÓÐÕߣ¬¾ßÓнá¹ûÖµ»ò throwable µÄÐÎʽ¡£¿É´Ó promise »ñÈ¡ future£¬ÔÚ promise ÉÏÉèÖÃÁ˽á¹ûºó£¬¾Í¿ÉÒÔÔڸà future ÉÏÉèÖô˽á¹û¡£

Ó¦Óà Scala ²¢·¢ÐÔ

ÏÖÔÚÄúÒÑÊìϤһЩ»ù±¾µÄ Scala ²¢·¢ÐÔ¸ÅÄÊÇʱºòÀ´Á˽âһϽâ¾ö Levenshtein ¾àÀëÎÊÌâµÄ´úÂëÁË¡£Çåµ¥ 5 ÏÔʾÁË Levenshtein ¾àÀë¼ÆËãµÄÒ»¸ö±È½Ï·ûºÏÓïÑÔϰ¹ßµÄ Scala ʵÏÖ£¬¸Ã´úÂë»ù±¾ÉÏÓë Çåµ¥ 1 ÖÐµÄ Java ´úÂëÀàËÆ£¬µ«²ÉÓÃÁ˺¯Êý·ç¸ñ¡£

Çåµ¥ 5. Scala ÖÐµÄ Levenshtein ¾àÀë¼ÆËã

val limit = targetText.length
/** Calculate edit distance from targetText to known word.
*
* @param word known word
* @param v0 int array of length targetText.length + 1
* @param v1 int array of length targetText.length + 1
* @return distance
*/
def editDistance(word: String, v0: Array[Int], v1: Array[Int]) = {

val length = word.length

@tailrec
def distanceByRow(rnum: Int, r0: Array[Int], r1: Array[Int]): Int = {
if (rnum >= length) r0(limit)
else {

// first element of r1 = delete (i+1) chars from target to match empty 'word'
r1(0) = rnum + 1

// use formula to fill in the rest of the row
for (j <- 0 until limit) {
val cost = if (word(rnum) == targetText(j)) 0 else 1
r1(j + 1) = min(r1(j) + 1, r0(j + 1) + 1, r0(j) + cost);
}

// recurse with arrays swapped for next row
distanceByRow(rnum + 1, r1, r0)
}
}

// initialize v0 (prior row of distances) as edit distance for empty 'word'
for (i <- 0 to limit) v0(i) = i

// recursively process rows matching characters in word being compared to find best
distanceByRow(0, v0, v1)
}

Çåµ¥ 5 ÖеĴúÂë¶Ôÿ¸öÐÐÖµ¼ÆËãʹÓÃÁËβ²¿µÝ¹é distanceByRow() ·½·¨¡£´Ë·½·¨Ê×Ïȼì²é¼ÆËãÁ˶àÉÙÐУ¬Èç¹û¸ÃÊý×ÖÓë¼ì²éµÄµ¥´ÊÖеÄ×Ö·ûÊýÆ¥Å䣬Ôò·µ»Ø½á¹û¾àÀë¡£·ñÔò»á¼ÆËãеÄÐÐÖµ£¬È»ºóµÝ¹éµØµ÷ÓÃ×ÔÉíÀ´¼ÆËãÏÂÒ»ÐУ¨½«Á½¸öÐÐÊý×é°ü×°Ôڸýø³ÌÖУ¬ÒÔ±ãÕýÈ·µØ´«µÝеÄ×îеÄÐÐÖµ£©¡£Scala ½«Î²²¿µÝ¹é·½·¨×ª»»ÎªÓë Java while Ñ­»·µÈЧµÄ´úÂ룬ËùÒÔ±£ÁôÁËÓë Java ´úÂëµÄÏàËÆÐÔ¡£

µ«ÊÇ£¬´Ë´úÂëÓë Java ´úÂëÖ®¼äÓÐÒ»¸öÖØ´óÇø±ð¡£Çåµ¥ 5 ÖÐµÄ for comprehension ʹÓÃÁ˱հü¡£±Õ°ü²¢²»×ÜÊǵõ½Á˵±Ç° JVM µÄ¸ßЧ´¦Àí£¨²ÎÔÄ Why is using for/foreach on a Range slow?£¬Á˽âÓйصÄÏêϸÐÅÏ¢£©£¬ËùÒÔËüÃÇÔڸüÆËãµÄ×îÀï²ãÑ­»·ÉÏÔö¼ÓÁË´óÁ¿¿ªÏú¡£ÈçÉÏËùÊö£¬Çåµ¥ 5 ÖеĴúÂëµÄÔËÐÐËÙ¶ÈûÓÐ Java °æ±¾ÄÇô¿ì¡£Çåµ¥ 6 ÖØÐ´ÁË´úÂ룬½« for comprehension Ìæ»»ÎªÌí¼ÓµÄβ²¿µÝ¹é·½·¨¡£Õâ¸ö°æ±¾ÒªÏêϸµÃ¶à£¬µ«Ö´ÐÐЧÂÊÓë Java °æ±¾Ï൱¡£

Çåµ¥ 6. ΪÌáÉýÐÔÄܶøÖØÐ¹¹ÔìµÄ¼ÆËã´úÂë

val limit = targetText.length

/** Calculate edit distance from targetText to known word.
*
* @param word known word
* @param v0 int array of length targetText.length + 1
* @param v1 int array of length targetText.length + 1
* @return distance
*/
def editDistance(word: String, v0: Array[Int], v1: Array[Int]) = {

val length = word.length

@tailrec
def distanceByRow(row: Int, r0: Array[Int], r1: Array[Int]): Int = {
if (row >= length) r0(limit)
else {

// first element of v1 = delete (i+1) chars from target to match empty 'word'
r1(0) = row + 1

// use formula recursively to fill in the rest of the row
@tailrec
def distanceByColumn(col: Int): Unit = {
if (col < limit) {
val cost = if (word(row) == targetText(col)) 0 else 1
r1(col + 1) = min(r1(col) + 1, r0(col + 1) + 1, r0(col) + cost)
distanceByColumn(col + 1)
}
}
distanceByColumn(0)

// recurse with arrays swapped for next row
distanceByRow(row + 1, r1, r0)
}
}

// initialize v0 (prior row of distances) as edit distance for empty 'word'
@tailrec
def initArray(index: Int): Unit = {
if (index <= limit) {
v0(index) = index
initArray(index + 1)
}
}
initArray(0)

// recursively process rows matching characters in word being compared to find best
distanceByRow(0, v0, v1)
}

Çåµ¥ 7 ¸ø³öµÄ Scala ´úÂëÖ´ÐÐÁËÓë Çåµ¥ 2 ÖÐµÄ Java ´úÂëÏàͬµÄ×èÈûµÄ¾àÀë¼ÆËã¡£bestMatch() ·½·¨ÕÒµ½ÓÉ Matcher ÀàʵÀý´¦ÀíµÄÌØ¶¨µ¥´Ê¿éÖÐÓëÄ¿±êÎı¾×îÆ¥ÅäµÄµ¥´Ê£¬Ê¹ÓÃβ²¿µÝ¹é best() ·½·¨À´É¨Ãèµ¥´Ê¡£*Distance Àà´´½¨¶à¸ö Matcher ʵÀý£¬Ã¿¸ö¶ÔÓ¦Ò»¸öµ¥´Ê¿é£¬È»ºóЭµ÷Æ¥Åä½á¹ûµÄÖ´ÐкÍ×éºÏ¡£

Çåµ¥ 7. Scala ÖÐʹÓöà¸öÏ̵߳ÄÒ»´Î×èÈû¾àÀë¼ÆËã

class Matcher(words: Array[String]) {

def bestMatch(targetText: String) = {

val limit = targetText.length
val v0 = new Array[Int](limit + 1)
val v1 = new Array[Int](limit + 1)

def editDistance(word: String, v0: Array[Int], v1: Array[Int]) = {
...
}

@tailrec
/** Scan all known words in range to find best match.
*
* @param index next word index
* @param bestDist minimum distance found so far
* @param bestMatch unique word at minimum distance, or None if not unique
* @return best match
*/
def best(index: Int, bestDist: Int, bestMatch: Option[String]): DistancePair =
if (index < words.length) {
val newDist = editDistance(words(index), v0, v1)
val next = index + 1
if (newDist < bestDist) best(next, newDist, Some(words(index)))
else if (newDist == bestDist) best(next, bestDist, None)
else best(next, bestDist, bestMatch)
} else DistancePair(bestDist, bestMatch)

best(0, Int.MaxValue, None)
}
}

class ParallelCollectionDistance(words: Array[String], size: Int) extends TimingTestBase {

val matchers = words.grouped(size).map(l => new Matcher(l)).toList

def shutdown = {}

def blockSize = size

/** Find best result across all matchers, using parallel collection. */
def bestMatch(target: String) = {
matchers.par.map(m => m.bestMatch(target)).
foldLeft(DistancePair.worstMatch)((a, m) => DistancePair.best(a, m))
}
}

class DirectBlockingDistance(words: Array[String], size: Int) extends TimingTestBase {

val matchers = words.grouped(size).map(l => new Matcher(l)).toList

def shutdown = {}

def blockSize = size

/** Find best result across all matchers, using direct blocking waits. */
def bestMatch(target: String) = {
import ExecutionContext.Implicits.global
val futures = matchers.map(m => future { m.bestMatch(target) })
futures.foldLeft(DistancePair.worstMatch)((a, v) =>
DistancePair.best(a, Await.result(v, Duration.Inf)))
}
}

Çåµ¥ 7 ÖеÄÁ½¸ö *Distance ÀàÏÔʾÁËЭµ÷ Matcher ½á¹ûµÄÖ´ÐкÍ×éºÏµÄ²»Í¬·½Ê½¡£ParallelCollectionDistance ʹÓÃÇ°ÃæÌáµ½µÄ Scala µÄ²¢Ðм¯ºÏ feature À´Òþ²Ø²¢ÐмÆËãµÄϸ½Ú£¬Ö»ÐèÒ»¸ö¼òµ¥µÄ foldLeft ¾Í¿ÉÒÔ×éºÏ½á¹û¡£

DirectBlockingDistance ¸ü¼ÓÃ÷È·£¬Ëü´´½¨ÁËÒ»×é future£¬È»ºóÔÚ¸ÃÁбíÉÏΪÿ¸ö½á¹ûʹÓÃÒ»¸ö foldLeft ºÍǶÌ×µÄ×èÈûµÈ´ý¡£

ÐÔÄÜÔÙ·ÖÎö

Çåµ¥ 7 ÖеÄÁ½¸ö *Distance ʵÏÖ¶¼ÊÇ´¦Àí Matcher ½á¹ûµÄºÏÀí·½·¨¡££¨ËüÃDz»½öºÏÀí£¬¶øÇҷdz£¸ßЧ¡£Ê¾Àý´úÂë °üº¬ÎÒÔÚÊÔÑéÖг¢ÊÔµÄÆäËûÁ½ÖÖʵÏÖ£¬µ«Î´°üº¬ÔÚ±¾ÎÄÖС££©ÔÚÕâÖÖÇé¿öÏ£¬ÐÔÄÜÊÇÒ»¸öÖ÷ÒªÎÊÌ⣬ËùÒÔͼ 3 ÏÔʾÁËÕâЩʵÏÖÏà¶ÔÓÚ Java ForkJoin ´úÂëµÄÐÔÄÜ¡£

ͼ 3. ForkJoinDistance Óë Scala Ìæ´ú·½°¸µÄÐÔÄܶԱÈ

ͼ 3 ÏÔʾ£¬Java ForkJoin ´úÂëµÄÐÔÄܱÈÿÖÖ Scala ʵÏÖ¶¼¸üºÃ£¬µ« DirectBlockingDistance ÔÚ 1,024 µÄ¿é´óСÏÂÌṩÁ˸üºÃµÄÐÔÄÜ¡£Á½ÖÖ Scala ʵÏÖÔڴ󲿷ֿé´óСÏ£¬¶¼ÌṩÁË±È Çåµ¥ 1 ÖÐµÄ ThreadPool ´úÂë¸üºÃµÄÐÔÄÜ¡£

ÕâЩÐÔÄܽá¹û½öÊÇÑÝʾ½á¹û£¬²»¾ßȨÍþÐÔ¡£Èç¹ûÄúÔÚ×Ô¼ºµÄϵͳÉÏÔËÐмÆÊ±²âÊÔ£¬¿ÉÄܻῴµ½²»Í¬µÄÐÔÄÜ£¬ÓÈÆäÔÚʹÓò»Í¬ÊýÁ¿µÄºËÐĵÄʱºò¡£Èç¹ûÏ£ÍûΪ¾àÀëÈÎÎñ»ñµÃ×î¼ÑµÄÐÔÄÜ£¬ÄÇô¿ÉÒÔʵÏÖһЩÓÅ»¯£º¿ÉÒÔ°´ÕÕ³¤¶È¶ÔÒÑÖªµ¥´Ê½øÐÐÅÅÐò£¬Ê×ÏÈÓ볤¶ÈºÍÊäÈëÏàͬµÄµ¥´Ê½øÐбȽϣ¨ÒòΪ±à¼­¾àÀë×ÜÊDz»µÍÓÚÓëµ¥´Ê³¤¶ÈÖ®²î£©¡£»òÕßÎÒ¿ÉÒÔÔÚ¾àÀë¼ÆË㳬³ö֮ǰµÄ×î¼Ñֵʱ£¬ÌáǰÍ˳ö¼ÆËã¡£µ«×÷Ϊһ¸öÏà¶Ô¼òµ¥µÄËã·¨£¬´ËÊÔÑ鹫ƽµØÕ¹Ê¾ÁËÁ½ÖÖ²¢·¢²Ù×÷ÊÇÈçºÎÌá¸ßÐÔÄܵģ¬ÒÔ¼°²»Í¬µÄ¹¤×÷¹²Ïí·½·¨µÄÓ°Ïì¡£

ÔÚÐÔÄÜ·½Ã棬Çåµ¥ 7 ÖÐµÄ Scale ¿ØÖÆ´úÂëÓë Çåµ¥ 2 ºÍ Çåµ¥ 3 ÖÐµÄ Java ´úÂëµÄ¶Ô±È½á¹ûºÜÓÐȤ¡£Scala ´úÂë¶ÌµÃ¶à£¬¶øÇÒ£¨¼ÙÉèÄúÊìϤ Scala£¡£©±È Java ´úÂë¸üÇåÎú¡£Scala ºÍ Java ¿ÉºÜºÃµÄÏ໥²Ù×÷£¬Äú¿ÉÒÔÔÚ±¾ÎÄµÄ ÍêÕûʾÀý´úÂë Öп´µ½£ºScala ´úÂë¶Ô Scala ºÍ Java ´úÂë¶¼ÔËÐÐÁ˼ÆÊ±²âÊÔ£¬Java ´úÂë½ø¶øÖ±½Ó´¦Àí Scala ´úÂëµÄ¸÷²¿·Ö¡£µÃÒæÓÚÕâÖÖÇáËɵĻ¥²Ù×÷ÐÔ£¬Äú¿ÉÒÔ½« Scala ÒýÈëÏÖÓÐµÄ Java ´úÂë¿âÖУ¬ÎÞÐè½øÐÐͨÅÌÐ޸ġ£×î³õʹÓà Scala Ϊ Java ´úÂëʵÏÖ¸ßˮƽ¿ØÖƳ£³£ºÜÓÐÓã¬ÕâÑùÄú¾Í¿ÉÒÔ³ä·ÖÀûÓà Scala Ç¿´óµÄ±í´ïÌØÐÔ£¬Í¬Ê±Ã»Óбհü»òת»»µÄÈκÎÖØ´óÐÔÄÜÓ°Ïì¡£

Çåµ¥ 7 ÖÐµÄ ParallelCollectionDistance Scala ´úÂëµÄ¼òµ¥ÐԷdz£¾ßÓÐÎüÒýÁ¦¡£Ê¹Óô˷½·¨£¬Äú¿ÉÒÔ´Ó´úÂëÖÐÍêÈ«³éÏó³ö²¢·¢ÐÔ£¬´Ó¶ø±àдÀàËÆµ¥Ïß³ÌÓ¦ÓóÌÐòµÄ´úÂ룬ͬʱÈÔÈ»»ñµÃ¶à¸ö´¦ÀíÆ÷µÄÓÅÊÆ¡£ÐÒÔ˵ÄÊÇ£¬¶ÔÓÚϲ»¶´Ë·½·¨µÄ¼òµ¥ÐÔµ«ÓÖ²»Ô¸Òâ»òÎÞ·¨Ö´ÐÐ Scala ¿ª·¢µÄÈ˶øÑÔ£¬Java 8 ´øÀ´ÁËÒ»ÖÖÖ´ÐÐÖ±½ÓµÄ Java ±à³ÌµÄÀàËÆÌØÐÔ¡£

½áÊøÓï

ÏÖÔÚÄúÒѾ­Á˽âÁË Java ºÍ Scala ²¢·¢ÐÔ²Ù×÷µÄ»ù´¡ÖªÊ¶£¬±¾ÏµÁÐÏÂһƪÎÄÕ½«½éÉÜ Java 8 ÈçºÎ¸Ä½ø¶Ô Java µÄ²¢·¢ÐÔÖ§³Ö£¨ÒÔ¼°´Ó³¤Ô¶À´½²£¬¿ÉÄÜ¶Ô Scala µÄ²¢·¢ÐÔÖ§³Ö£©¡£Java 8 µÄÐí¶à¸Ä¶¯Äú¿´ÆðÀ´¿ÉÄܶ¼ºÜÊìϤ£¨Scala ²¢·¢ÐÔÌØÐÔÖÐʹÓõÄÐí¶àÏàͬµÄ¸ÅÄî¶¼°üº¬ÔÚ Java 8 ÖУ©£¬ËùÒÔÄúºÜ¿ì¾ÍÄܹ»ÔÚÆÕͨµÄ Java ´úÂëÖÐʹÓÃһЩ Scala ¼¼Êõ¡£ÇëÔĶÁÏÂÒ»ÆÚÎÄÕ£¬Á˽âÓ¦¸ÃÈçºÎ×ö¡£

   
2724 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

Java΢·þÎñÐÂÉú´úÖ®Nacos
ÉîÈëÀí½âJavaÖеÄÈÝÆ÷
JavaÈÝÆ÷Ïê½â
Java´úÂëÖÊÁ¿¼ì²é¹¤¾ß¼°Ê¹Óð¸Àý
Ïà¹ØÎĵµ

JavaÐÔÄÜÓÅ»¯
Spring¿ò¼Ü
SSM¿ò¼Ü¼òµ¥¼òÉÜ
´ÓÁ㿪ʼѧjava±à³Ì¾­µä
Ïà¹Ø¿Î³Ì

¸ßÐÔÄÜJava±à³ÌÓëϵͳÐÔÄÜÓÅ»¯
JavaEE¼Ü¹¹¡¢ Éè¼ÆÄ£Ê½¼°ÐÔÄܵ÷ÓÅ
Java±à³Ì»ù´¡µ½Ó¦Óÿª·¢
JAVAÐéÄâ»úÔ­ÀíÆÊÎö
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

Java ÖеÄÖÐÎıàÂëÎÊÌâ
Java»ù´¡ÖªÊ¶µÄÈýÊ®¸ö¾­µäÎÊ´ð
Íæ×ª Java Web Ó¦Óÿª·¢
ʹÓÃSpring¸üºÃµØ´¦ÀíStruts
ÓÃEclipse¿ª·¢iPhone WebÓ¦ÓÃ
²å¼þϵͳ¿ò¼Ü·ÖÎö


Struts+Spring+Hibernate
»ùÓÚJ2EEµÄWeb 2.0Ó¦Óÿª·¢
J2EEÉè¼ÆÄ£Ê½ºÍÐÔÄܵ÷ÓÅ
Java EE 5ÆóÒµ¼¶¼Ü¹¹Éè¼Æ
Javaµ¥Ôª²âÊÔ·½·¨Óë¼¼Êõ
Java±à³Ì·½·¨Óë¼¼Êõ


Struts+Spring+Hibernate/EJB+ÐÔÄÜÓÅ»¯
»ªÏÄ»ù½ð ActiveMQ Ô­ÀíÓë¹ÜÀí
ijÃñº½¹«Ë¾ Java»ù´¡±à³Ìµ½Ó¦Óÿª·¢
ij·çµç¹«Ë¾ Java Ó¦Óÿª·¢Æ½Ì¨ÓëÇ¨ÒÆ
ÈÕÕÕ¸Û J2EEÓ¦Óÿª·¢¼¼Êõ¿ò¼ÜÓëʵ¼ù
ij¿ç¹ú¹«Ë¾ ¹¤×÷Á÷¹ÜÀíJBPM
¶«·½º½¿Õ¹«Ë¾ ¸ß¼¶J2EE¼°ÆäÇ°ÑØ¼¼Êõ