Á˽â
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 ¼¼Êõ¡£ÇëÔĶÁÏÂÒ»ÆÚÎÄÕ£¬Á˽âÓ¦¸ÃÈçºÎ×ö¡£
|