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

1Ôª 10Ôª 50Ôª





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



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
¸ß²¢·¢µÄ¡°´óɱÆ÷¡±£ºÒì²½»¯¡¢²¢Ðл¯
 
  6326  次浏览      30
 2018-11-13
 
±à¼­ÍƼö:

±¾ÎÄÀ´×ÔÓÚ51cto£¬ÎÄÕ´ÓÒì²½»¯ºÍ²¢Ðл¯Á½¸ö·½°¸Öиø´ó¼Ò½éÉÜÈçºÎ´¦Àí¼Ü¹¹Éè¼ÆÖеĸ߲¢·¢Õâ¸öÎÊÌâ¡£

¸ß²¢·¢µÄ´óɱÆ÷£ºÒì²½»¯

ͬ²½ºÍÒì²½£¬×èÈûºÍ·Ç×èÈû

ͬ²½ºÍÒì²½£¬×èÈûºÍ·Ç×èÈû£¬Õ⼸¸ö´ÊÒѾ­ÊÇÀÏÉú³£Ì¸£¬µ«ÊÇ»¹ÊÇÓкܶàͬѧ·Ö²»Çå³þ£¬ÒÔΪͬ²½¿Ï¶¨¾ÍÊÇ×èÈû£¬Òì²½¿Ï¶¨¾ÍÊÇ·Ç×èÈû£¬ÆäʵËûÃDz¢²»ÊÇÒ»»ØÊ¡£

ͬ²½ºÍÒì²½¹Ø×¢µÄÊǽá¹ûÏûÏ¢µÄͨÐÅ»úÖÆ£º

ͬ²½£ºµ÷Ó÷½ÐèÒªÖ÷¶¯µÈ´ý½á¹ûµÄ·µ»Ø¡£

Òì²½£º²»ÐèÒªÖ÷¶¯µÈ´ý½á¹ûµÄ·µ»Ø£¬¶øÊÇͨ¹ýÆäËûÊֶΣ¬±ÈÈç״̬֪ͨ£¬»Øµ÷º¯ÊýµÈ¡£

×èÈûºÍ·Ç×èÈûÖ÷Òª¹Ø×¢µÄÊǵȴý½á¹û·µ»Øµ÷Ó÷½µÄ״̬£º

×èÈû£ºÊÇÖ¸½á¹û·µ»ØÖ®Ç°£¬µ±Ç°Ï̱߳»¹ÒÆð£¬²»×öÈκÎÊ¡£

·Ç×èÈû£ºÊÇÖ¸½á¹ûÔÚ·µ»ØÖ®Ç°£¬Ï߳̿ÉÒÔ×öһЩÆäËûÊ£¬²»»á±»¹ÒÆð¡£

¿ÉÒÔ¿´¼ûͬ²½ºÍÒì²½£¬×èÈûºÍ·Ç×èÈûÖ÷Òª¹Ø×¢µÄµã²»Í¬£¬ÓÐÈË»áÎÊͬ²½»¹ÄÜ·Ç×èÈû£¬Òì²½»¹ÄÜ×èÈû?

µ±È»ÊÇ¿ÉÒԵģ¬ÏÂÃæÎªÁ˸üºÃµÄ˵Ã÷ËüÃǵÄ×éºÏÖ®¼äµÄÒâ˼£¬Óü¸¸ö¼òµ¥µÄÀý×Ó˵Ã÷£º

ͬ²½×èÈû£ºÍ¬²½×èÈû»ù±¾Ò²ÊDZà³ÌÖÐ×î³£¼ûµÄÄ£ÐÍ£¬´ò¸ö±È·½ÄãÈ¥É̵êÂòÒ·þ£¬ÄãÈ¥ÁËÖ®ºó·¢ÏÖÒ·þÂôÍêÁË£¬ÄÇÄã¾ÍÔÚµêÀïÃæÒ»Ö±µÈ£¬ÆÚ¼ä²»×öÈκÎÊÂ(°üÀ¨¿´ÊÖ»ú)£¬µÈ×ÅÉ̼ҽø»õ£¬Ö±µ½ÓлõΪֹ£¬Õâ¸öЧÂʺܵ͡£

ͬ²½·Ç×èÈû£ºÍ¬²½·Ç×èÈûÔÚ±à³ÌÖпÉÒÔ³éÏóΪһ¸öÂÖѯģʽ£¬ÄãÈ¥ÁËÉ̵êÖ®ºó£¬·¢ÏÖÒ·þÂôÍêÁË¡£

Õâ¸öʱºò²»ÐèҪɵɵµÄµÈ×Å£¬Äã¿ÉÒÔÈ¥ÆäËûµØ·½±ÈÈçÄ̲èµê£¬Âò±­Ë®£¬µ«ÊÇÄ㻹ÊÇÐèҪʱ²»Ê±µÄÈ¥É̵êÎÊÀϰåÐÂÒ·þµ½ÁËÂð¡£

Òì²½×èÈû£ºÒì²½×èÈûÕâ¸ö±à³ÌÀïÃæÓõĽÏÉÙ£¬ÓеãÀàËÆÄãдÁ˸öÏ̳߳أ¬submit È»ºóÂíÉÏ future.get()£¬ÕâÑùÏß³ÌÆäʵ»¹ÊÇ¹ÒÆðµÄ¡£

ÓеãÏñÄãÈ¥É̵êÂòÒ·þ£¬Õâ¸öʱºò·¢ÏÖÒ·þûÓÐÁË£¬Õâ¸öʱºòÄã¾Í¸øÀϰåÁô¸öµç»°£¬ËµÒ·þµ½Á˾͸øÎÒ´òµç»°£¬È»ºóÄã¾ÍÊØ×ÅÕâ¸öµç»°£¬Ò»Ö±µÈ×ÅËüÏìʲôÊÂÒ²²»×ö¡£ÕâÑù¸Ð¾õµÄÈ·Óеãɵ£¬ËùÒÔÕâ¸öģʽÓõñȽÏÉÙ¡£

Òì²½·Ç×èÈû£ºÕâÒ²ÊÇÏÖÔڸ߲¢·¢±à³ÌµÄÒ»¸öºËÐÄ£¬Ò²ÊǽñÌìÖ÷Òª½²µÄÒ»¸öºËÐÄ¡£

ºÃ±ÈÄãÈ¥É̵êÂòÒ·þ£¬Ò·þûÁË£¬ÄãÖ»ÐèÒª¸øÀϰå˵ÕâÊÇÎҵĵ绰£¬Ò·þµ½Á˾ʹò¡£È»ºóÄã¾ÍËæÐÄËùÓûµÄÈ¥Íæ£¬Ò²²»ÓòÙÐÄÒ·þʲôʱºòµ½£¬Ò·þÒ»µ½£¬µç»°Ò»Ïì¾Í¿ÉÒÔÈ¥ÂòÒ·þÁË¡£

ͬ²½×èÈû PK Òì²½·Ç×èÈû

ÉÏÃæÒѾ­¿´µ½ÁËͬ²½×èÈûµÄЧÂÊÊǶàôµÄµÍ£¬Èç¹ûʹÓÃͬ²½×èÈûµÄ·½Ê½È¥ÂòÒ·þ£¬ÄãÓпÉÄÜÒ»ÌìÖ»ÄÜÂòÒ»¼þÒ·þ£¬ÆäËûʲôʶ¼²»ÄܸÉ;Èç¹ûÓÃÒì²½·Ç×èÈûµÄ·½Ê½È¥Âò£¬ÂòÒ·þÖ»ÊÇÄãÒ»ÌìÖнøÐеÄÒ»¸öСÊ¡£

ÎÒÃǰÑÕâ¸öÓ³Éäµ½ÎÒÃÇ´úÂëÖУ¬µ±ÎÒÃǵÄÏ̷߳¢ÉúÒ»´Î RPC µ÷ÓûòÕß HTTP µ÷Óã¬ÓÖ»òÕ߯äËûµÄһЩºÄʱµÄ IO µ÷Óá£

·¢ÆðÖ®ºó£¬Èç¹ûÊÇͬ²½×èÈû£¬ÎÒÃǵÄÕâ¸öÏ߳̾ͻᱻ×èÈû¹ÒÆð£¬Ö±µ½½á¹û·µ»Ø£¬ÊÔÏëһϣ¬Èç¹û IO µ÷ÓÃºÜÆµ·±ÄÇÎÒÃÇµÄ CPU ʹÓÃÂÊ»áºÜµÍºÜµÍ¡£

ÕýËùνÊÇÎᄀÆäÓ㬼ÈÈ» CPU µÄʹÓÃÂʱ» IO µ÷ÓøãµÃºÜµÍ£¬ÄÇÎÒÃǾͿÉÒÔʹÓÃÒì²½·Ç×èÈû¡£

µ±·¢Éú IO µ÷ÓÃʱÎÒ²¢²»ÂíÉϹØÐĽá¹û£¬ÎÒÖ»ÐèÒª°Ñ»Øµ÷º¯ÊýдÈëÕâ´Î IO µ÷Óã¬Õâ¸öʱºòÏ߳̿ÉÒÔ¼ÌÐø´¦ÀíеÄÇëÇ󣬵± IO µ÷ÓýáÊøÊ±£¬»áµ÷Óûص÷º¯Êý¡£

¶øÎÒÃǵÄÏß³ÌʼÖÕ´¦ÓÚæµ֮ÖУ¬ÕâÑù¾ÍÄÜ×ö¸ü¶àµÄÓÐÒâÒåµÄÊÂÁË¡£ÕâÀïÊ×ÏÈҪ˵Ã÷µÄÊÇ£¬Òì²½»¯²»ÊÇÍòÄÜ£¬Òì²½»¯²¢²»ÄÜËõ¶ÌÄãÕû¸öÁ´Â·µ÷ÓÃʱ¼ä³¤µÄÎÊÌ⣬µ«ÊÇËüÄܼ«´óµÄÌáÉýÄãµÄ×î´ó QPS¡£

Ò»°ãÎÒÃǵÄÒµÎñÖÐÓÐÁ½´¦±È½ÏºÄʱ£º

CPU£ºCPU ºÄʱָµÄÊÇÎÒÃǵÄÒ»°ãµÄÒµÎñ´¦ÀíÂß¼­£¬±ÈÈçһЩÊý¾ÝµÄÔËË㣬¶ÔÏóµÄÐòÁл¯¡£ÕâЩÒì²½»¯ÊDz»Äܽâ¾öµÄ£¬µÃÐèÒª¿¿Ò»Ð©Ëã·¨µÄÓÅ»¯£¬»òÕßһЩ¸ßÐÔÄÜ¿ò¼Ü¡£

IO Wait£ºIO ºÄʱ¾ÍÏñÎÒÃÇÉÏÃæËµµÄ,Ò»°ã·¢ÉúÔÚÍøÂçµ÷Óã¬Îļþ´«ÊäÖеȵȣ¬Õâ¸öʱºòÏß³ÌÒ»°ã»á¹ÒÆð×èÈû¡£¶øÎÒÃǵÄÒì²½»¯Í¨³£ÓÃÓÚ½â¾öÕⲿ·ÖµÄÎÊÌâ¡£

ÄÄЩ¿ÉÒÔÒì²½»¯

ÉÏÃæËµÁËÒì²½»¯ÊÇÓÃÓÚ½â¾ö IO ×èÈûµÄÎÊÌ⣬¶øÎÒÃÇÒ»°ãÏîÄ¿ÖпÉÒÔʹÓÃÒì²½»¯µÄÇé¿öÈçÏ£º

Servlet Òì²½»¯

Spring MVC Òì²½»¯

RPC µ÷ÓÃÈç(Dubbo£¬Thrift)£¬HTTP µ÷ÓÃÒì²½»¯

Êý¾Ý¿âµ÷Ó㬻º´æµ÷ÓÃÒì²½»¯

ÏÂÃæÎÒ»á´ÓÉÏÃæ¼¸¸ö·½Ãæ½øÐÐÒì²½»¯µÄ½éÉÜ¡£

Servlet Òì²½»¯

¶ÔÓÚ Java ¿ª·¢³ÌÐòÔ±À´Ëµ Servlet ²¢²»Ä°Éú£¬ÔÚÏîÄ¿Öв»ÂÛÄãʹÓà Struts2£¬»¹ÊÇʹÓÃµÄ Spring MVC£¬±¾ÖÊÉ϶¼ÊÇ·â×°µÄ Servlet¡£

µ«ÊÇÎÒÃÇÒ»°ãµÄ¿ª·¢¶¼ÊÇʹÓõÄͬ²½×èÈû£¬Ä£Ê½ÈçÏ£º

ÉÏÃæµÄģʽÓŵãÔÚÓÚ±àÂë¼òµ¥£¬ÊʺÏÔÚÏîÄ¿Æô¶¯³õÆÚ£¬·ÃÎÊÁ¿½ÏÉÙ£¬»òÕßÊÇ CPU ÔËËã½Ï¶àµÄÏîÄ¿¡£

ȱµãÔÚÓÚ£¬ÒµÎñÂß¼­Ïß³ÌºÍ Servlet ÈÝÆ÷Ïß³ÌÊÇͬһ¸ö£¬Ò»°ãµÄÒµÎñÂß¼­×ܵ÷¢Éúµã IO£¬±ÈÈç²éѯÊý¾Ý¿â£¬±ÈÈç²úÉú RPC µ÷Óã¬Õâ¸öʱºò¾Í»á·¢Éú×èÈû¡£

¶øÎÒÃÇµÄ Servlet ÈÝÆ÷Ï߳̿϶¨ÊÇÓÐÏ޵쬵± Servlet ÈÝÆ÷Ï̶߳¼±»×èÈûµÄʱºòÎÒÃǵķþÎñÕâ¸öʱºò¾Í»á·¢Éú¾Ü¾ø·ÃÎÊ£¬Ï̲߳»¹»ÎÒµ±È»¿ÉÒÔͨ¹ýÔö¼Ó»úÆ÷µÄһϵÁÐÊÖ¶ÎÀ´½â¾öÕâ¸öÎÊÌâ¡£

µ«ÊÇË×»°ËµµÃºÃ¿¿È˲»Èç¿¿×Ô¼º£¬¿¿±ðÈËÌæÎÒ·Öµ£ÇëÇ󣬻¹²»ÈçÎÒ×Ô¼º¸ã¶¨¡£

ËùÒÔÔÚ Servlet 3.0 Ö®ºóÖ§³ÖÁËÒì²½»¯£¬ÎÒÃDzÉÓÃÒì²½»¯Ö®ºó£¬Ä£Ê½±ä³ÉÈçÏ£º

ÔÚÕâÀïÎÒÃDzÉÓÃеÄÏ̴߳¦ÀíÒµÎñÂß¼­£¬IO µ÷ÓõÄ×èÈû¾Í²»»áÓ°ÏìÎÒÃÇµÄ Serlvet ÁË£¬ÊµÏÖÒì²½ Serlvet µÄ´úÂëÒ²±È½Ï¼òµ¥£¬ÈçÏ£º

@WebServlet(name = "WorkServlet",urlPatterns = "/work",asyncSupported =true)
public class WorkServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//ÉèÖÃContentType,¹Ø±Õ»º´æ
resp.setContentType("text/plain;charset=UTF-8");
resp.setHeader("Cache-Control","private");
resp.setHeader("Pragma","no-cache");
final PrintWriter writer= resp.getWriter();
writer.println("ÀÏʦ¼ì²é×÷ÒµÁË");
writer.flush();
List<String> zuoyes=new ArrayList<String>();
for (int i = 0; i < 10; i++) {
zuoyes.add("zuoye"+i);;
}
//¿ªÆôÒì²½ÇëÇó
final AsyncContext ac=req.startAsync();
doZuoye(ac, zuoyes);
writer.println("ÀÏʦ²¼ÖÃ×÷Òµ");
writer.flush();
}

private void doZuoye(final AsyncContext ac, final List<String> zuoyes) {
ac.setTimeout(1*60*60*1000L);
ac.start(new Runnable() {
@Override
public void run() {
//ͨ¹ýresponse»ñµÃ×Ö·ûÊä³öÁ÷
try {
PrintWriter writer=ac.getResponse().getWriter();
for (String zuoye:zuoyes) {
writer.println("\""+zuoye+"\"ÇëÇó´¦ÀíÖÐ");
Thread.sleep(1*1000L);
writer.flush();
}
ac.complete();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}

ʵÏÖ Serlvet µÄ¹Ø¼üÔÚÓÚ HTTP ²ÉÈ¡Á˳¤Á¬½Ó£¬Ò²¾ÍÊǵ±ÇëÇó´ò¹ýÀ´µÄʱºò¾ÍËãÓзµ»ØÒ²²»»á¹Ø±Õ£¬ÒòΪ¿ÉÄÜ»¹»áÓÐÊý¾Ý£¬Ö±µ½·µ»Ø¹Ø±ÕÖ¸Áî¡£

AsyncContext ac=req.startAsync();ÓÃÓÚ»ñÈ¡Òì²½ÉÏÏÂÎÄ£¬ºóÐøÎÒÃÇͨ¹ýÕâ¸öÒì²½ÉÏÏÂÎĽøÐлص÷·µ»ØÊý¾Ý£¬ÓеãÏñÎÒÃÇÂòÒ·þµÄʱºò£¬Áô¸øÀϰåÒ»¸öµç»°¡£

¶øÕâ¸öÉÏÏÂÎÄÒ²ÊÇÒ»¸öµç»°£¬µ±ÓÐÒ·þµ½µÄʱºò£¬Ò²¾ÍÊǵ±ÓÐÊý¾Ý×¼±¸ºÃµÄʱºò¾Í¿ÉÒÔ´òµç»°·¢ËÍÊý¾ÝÁË¡£ac.complete();ÓÃÀ´½øÐг¤Á´½ÓµÄ¹Ø±Õ¡£

Spring MVC Òì²½»¯

ÏÖÔÚÆäʵºÜÉÙÈËÀ´½øÐÐ Serlvet ±à³Ì£¬¶¼ÊÇÖ±½Ó²ÉÓÃÏֳɵÄһЩ¿ò¼Ü£¬±ÈÈç Struts2£¬Spring MVC¡£ÏÂÃæ½éÉÜÏÂʹÓà Spring MVC ÈçºÎ½øÐÐÒì²½»¯£º

Ê×ÏÈÈ·ÈÏÄãµÄÏîÄ¿ÖÐµÄ Servlet ÊÇ 3.0 ÒÔÉÏ£¬Æä´Î Spring MVC 4.0+£º

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>

web.xml Í·²¿ÉùÃ÷£¬±ØÐëÒª 3.0£¬Filter ºÍ Serverlet ÉèÖÃΪÒì²½£º

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml
/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<filter>
<filter-name>testFilter</filter-name>
<filter-class>com.TestFilter</filter-class>
<async-supported>true</async-supported>
</filter>

<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
.........
<async-supported>true</async-supported>
</servlet>

ʹÓà Spring MVC ·â×°ÁË Servlet µÄ AsyncContext£¬Ê¹ÓÃÆðÀ´±È½Ï¼òµ¥¡£ÒÔǰÎÒÃÇͬ²½µÄģʽµÄ Controller ÊÇ·µ»Ø ModelAndView¡£

¶øÒ첽ģʽֱ½ÓÉú³ÉÒ»¸ö DeferredResult(Ö§³ÖÎÒÃdz¬Ê±À©Õ¹)¼´¿É±£´æÉÏÏÂÎÄ£¬ÏÂÃæ¸ø³öÈçºÎºÍÎÒÃÇ HttpClient ´îÅäµÄ¼òµ¥ demo£º

@RequestMapping(value="/asynctask", method = RequestMethod.GET)
public DeferredResult<String> asyncTask()
throws IOReactorException {
IOReactorConfig ioReactorConfig = IOReactorConfig.custom().setIoThreadCount(1).build();
ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);
PoolingNHttpClientConnectionManager conManager = new PoolingNHttpClientConnectionManager(ioReactor);
conManager.setMaxTotal(100);
conManager.setDefaultMaxPerRoute(100);
CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom().setConnectionManager
(conManager).build();
// Start the client
httpclient.start();
//ÉèÖó¬Ê±Ê±¼ä200ms
final DeferredResult<String> deferredResult = new DeferredResult<String>(200L);
deferredResult.onTimeout(new Runnable() {
@Override
public void run() {
System.out.println("Òì²½µ÷ÓÃÖ´Ðг¬Ê±£¡thread id is : " + Thread.currentThread().getId());
deferredResult.setResult("³¬Ê±ÁË");
}
});
System.out.println("/asynctask µ÷Óã¡thread id is : " + Thread.currentThread().getId());
final HttpGet request2 = new HttpGet("http://www.apache.org
/");
httpclient.execute(request2, new FutureCallback
<HttpResponse>() {

public void completed(final HttpResponse response2) {
System.out.println(request2.getRequestLine() + "->" + response2.getStatusLine());
deferredResult.setResult(request2.getRequestLine() + "->" + response2.getStatusLine());
}

public void failed(final Exception ex) {
System.out.println(request2.getRequestLine() + "->" + ex);
}

public void cancelled() {
System.out.println(request2.getRequestLine() + " cancelled");
}

});
return deferredResult;
}

×¢Ò⣺ÔÚ Serlvet Òì²½»¯ÖÐÓиöÎÊÌâÊÇ Filter µÄºóÖýá¹û´¦Àí£¬Ã»·¨Ê¹Ó㬶ÔÓÚÎÒÃÇһЩ´òµã£¬½á¹ûͳ¼ÆÖ±½ÓʹÓà Serlvet Òì²½ÊÇû·¨Óõġ£

ÔÚ Spring MVC ÖоͺܺõĽâ¾öÁËÕâ¸öÎÊÌ⣬Spring MVC ²ÉÓÃÁËÒ»¸ö±È½ÏÈ¡Çɵķ½Ê½Í¨¹ýÇëÇóת·¢£¬ÄÜÈÃÇëÇóÔÙ´Îͨ¹ý¹ýÂËÆ÷¡£

µ«ÊÇÓÖÒýÈëÁËеÄÒ»¸öÎÊÌâÄǾÍÊǹýÂËÆ÷»á´¦ÀíÁ½´Î£¬ÕâÀï¿ÉÒÔͨ¹ý Spring MVC Ô´ÂëÖÐ×ÔÉíÅжϵķ½·¨¡£

ÎÒÃÇ¿ÉÒÔÔÚ Filter ÖÐʹÓÃÏÂÃæÕâ¾ä»°À´½øÐÐÅжÏÊDz»ÊÇÊôÓÚ Spring MVC ת·¢¹ýÀ´µÄÇëÇ󣬴Ӷø²»´¦Àí Filter µÄǰÖÃʼþ£¬Ö»´¦ÀíºóÖÃʼþ£º

Object asyncManagerAttr = servletRequest.getAttribute(WEB_ASYNC_MANAGER_ATTRIBUTE);
return asyncManagerAttr instanceof WebAsyncManager ;

È«Á´Â·Òì²½»¯

ÉÏÃæÎÒÃǽéÉÜÁË Serlvet µÄÒì²½»¯£¬ÏàÐÅϸÐĵÄͬѧ¶¼¿´³öÀ´Ëƺõ²¢Ã»Óнâ¾ö¸ù±¾µÄÎÊÌ⣬ÎÒµÄ IO ×èÈûÒÀÈ»´æÔÚ£¬Ö»ÊÇ»»Á˸öλÖöøÒÑ¡£

µ± IO µ÷ÓÃÆµ·±Í¬Ñù»áÈÃÒµÎñÏ̳߳ؿìËÙ±äÂú£¬ËäÈ» Serlvet ÈÝÆ÷Ï̲߳»±»×èÈû£¬µ«ÊÇÕâ¸öÒµÎñÒÀÈ»»á±äµÃ²»¿ÉÓá£

ÄÇôÔõô²ÅÄܽâ¾öÉÏÃæµÄÎÊÌâÄØ?´ð°¸¾ÍÊÇÈ«Á´Â·Òì²½»¯£¬È«Á´Â·Òì²½×·ÇóµÄÊÇûÓÐ×èÈû£¬´òÂúÄãµÄ CPU£¬°Ñ»úÆ÷µÄÐÔÄÜѹեµ½¼«Ö¡£Ä£ÐÍͼÈçÏ£º

¾ßÌåµÄ NIO Client µ½µ××öÁËʲôÊÂÄØ£¬¾ßÌåÈçÏÂÃæÄ£ÐÍ£º

ÉÏÃæ¾ÍÊÇÎÒÃÇÈ«Á´Â·Òì²½µÄͼÁË(²¿·ÖÏ̳߳ؿÉÒÔÓÅ»¯)¡£È«Á´Â·µÄºËÐÄÔÚÓÚÖ»ÒªÎÒÃÇÓöµ½ IO µ÷ÓõÄʱºò£¬ÎÒÃǾͿÉÒÔʹÓà NIO£¬´Ó¶ø±ÜÃâ×èÈû£¬Ò²¾Í½â¾öÁË֮ǰ˵µÄÒµÎñÏ̳߳ر»´òÂúµÄÞÏÞγ¡¾°¡£

Ô¶³Ìµ÷ÓÃÒì²½»¯

ÎÒÃÇÒ»°ãÔ¶³Ìµ÷ÓÃʹÓà RPC »òÕß HTTP£º

¶ÔÓÚ RPC À´Ëµ£¬Ò»°ã Thrift£¬HTTP£¬Motan µÈÖ§³Ö¶¼Òì²½µ÷Óã¬ÆäÄÚ²¿Ô­ÀíÒ²¶¼ÊDzÉÓÃʼþÇý¶¯µÄ NIO Ä£ÐÍ¡£

¶ÔÓÚ HTTP À´Ëµ£¬Ò»°ãµÄ Apache HTTP Client ºÍ Okhttp Ò²¶¼ÌṩÁËÒì²½µ÷Óá£

ÏÂÃæ¼òµ¥½éÉÜÏ HTTP Òì²½»¯µ÷ÓÃÊÇÔõô×öµÄ¡£Ê×ÏÈÀ´¿´Ò»¸öÀý×Ó£º

public class HTTPAsyncClientDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException, IOReactorException {
//¾ßÌå²ÎÊýº¬ÒåÏÂÎĻὲ
//apacheÌṩÁËioReactorµÄ²ÎÊýÅäÖã¬ÕâÀïÎÒÃÇÅäÖÃIO Ïß³ÌΪ1
IOReactorConfig ioReactorConfig = IOReactorConfig.custom().setIoThreadCount(1).build();
//¸ù¾ÝÕâ¸öÅäÖô´½¨Ò»¸öioReactor
ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);
//asyncHttpClientʹÓÃPoolingNHttpClientConnectionManager¹ÜÀíÎÒÃǿͻ§¶ËÁ¬½Ó
PoolingNHttpClientConnectionManager conManager = new PoolingNHttpClientConnectionManager(ioReactor);
//ÉèÖÃ×ܹ²µÄÁ¬½ÓµÄ×î´óÊýÁ¿
conManager.setMaxTotal(100);
//ÉèÖÃÿ¸ö·ÓɵÄÁ¬½ÓµÄ×î´óÊýÁ¿
conManager.setDefaultMaxPerRoute(100);
//´´½¨Ò»¸öClient
CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom().setConnectionManager
(conManager).build();
// Start the client
httpclient.start();

// Execute request
final HttpGet request1 = new HttpGet("http://www.apache.org/");
Future<HttpResponse> future = httpclient.execute
(request1, null);
// and wait until a response is received
HttpResponse response1 = future.get();
System.out.println(request1.getRequestLine() + "->" + response1.getStatusLine());

// One most likely would want to use a callback
for operation result
final HttpGet request2 = new HttpGet("http://www.apache.org/");
httpclient.execute(request2, new FutureCallback
<HttpResponse>() {
//Complete³É¹¦ºó»á»Øµ÷Õâ¸ö·½·¨
public void completed(final HttpResponse response2) {
System.out.println(request2.getRequestLine() + "->" + response2.getStatusLine());
}

public void failed(final Exception ex) {
System.out.println(request2.getRequestLine() + "->" + ex);
}

public void cancelled() {
System.out.println(request2.getRequestLine() + " cancelled");
}

});
}
}

ÏÂÃæ¸ø³ö httpAsync µÄÕû¸öÀàͼ£º

¶ÔÓÚÎÒÃÇµÄ HTTPAysncClient ×îºóʹÓõÄÊÇ InternalHttpAsyncClient£¬ÔÚ InternalHttpAsyncClient ÖÐÓиö ConnectionManager£¬Õâ¸ö¾ÍÊÇÎÒÃǹÜÀíÁ¬½ÓµÄ¹ÜÀíÆ÷¡£

¶øÔÚ httpAsync ÖÐÖ»ÓÐÒ»¸öʵÏÖÄǾÍÊÇ PoolingNHttpClientConnectionManager¡£

Õâ¸öÁ¬½Ó¹ÜÀíÆ÷ÖÐÓÐÁ½¸öÎÒÃDZȽϹØÐĵģ¬Ò»¸öÊÇ Reactor£¬Ò»¸öÊÇ Cpool£º

Reactor£ºËùÓÐµÄ Reactor ÕâÀï¶¼ÊÇʵÏÖÁË IOReactor ½Ó¿Ú¡£ÔÚ PoolingNHttpClientConnectionManager ÖлáÓÐÓµÓÐÒ»¸ö Reactor£¬ÄǾÍÊÇ DefaultConnectingIOReactor£¬Õâ¸ö DefaultConnectingIOReactor£¬¸ºÔð´¦Àí Acceptor¡£

ÔÚ DefaultConnectingIOReactor Óиö excutor ·½·¨£¬Éú³É IOReactor Ò²¾ÍÊÇÎÒÃÇͼÖÐµÄ BaseIOReactor£¬½øÐÐ IO µÄ²Ù×÷¡£Õâ¸öÄ£Ð;ÍÊÇÎÒÃÇÉÏÃæµÄ 1.2.2 µÄÄ£ÐÍ¡£

CPool£ºÔÚ PoolingNHttpClientConnectionManager ÖÐÓиö CPool£¬Ö÷ÒªÊǸºÔð¿ØÖÆÎÒÃÇÁ¬½Ó£¬ÎÒÃÇÉÏÃæËù˵µÄ maxTotal ºÍ defaultMaxPerRoute£¬¶¼ÊÇÓÉÆä½øÐпØÖÆ¡£

Èç¹ûÿ¸ö·ÓÉÓÐÂúÁË£¬Ëü»á¶Ï¿ª×îÀϵÄÒ»¸öÁ´½Ó;Èç¹û×ܹ²µÄ total ÂúÁË£¬Ëü»á·ÅÈë leased ¶ÓÁУ¬ÊͷſռäµÄʱºò¾Í»á½«ÆäÖØÐÂÁ¬½Ó¡£

Êý¾Ý¿âµ÷ÓÃÒì²½»¯

¶ÔÓÚÊý¾Ý¿âµ÷ÓÃÒ»°ãµÄ¿ò¼Ü²¢Ã»ÓÐÌṩÒì²½»¯µÄ·½·¨£¬ÕâÀïÍÆ¼ö×Ô¼º·â×°»òÕßʹÓÃÍøÉÏ¿ªÔ´µÄ¡£

Òì²½»¯²¢²»ÊǸ߲¢·¢µÄÒøµ¯£¬µ«ÊÇÓÐÁËÒì²½»¯µÄÈ·ÄÜÌá¸ßÄã»úÆ÷µÄ QPS£¬ÍÌÍÂÁ¿µÈµÈ¡£

ÉÏÊö½²µÄһЩģÐÍÈç¹ûÄܺÏÀíµÄ×öһЩÓÅ»¯£¬È»ºó½øÐÐÓ¦Óã¬ÏàÐÅÄܶÔÄãµÄ·þÎñÓкܴóµÄ°ïÖú¡£

¸ß²¢·¢´óɱÆ÷£º²¢Ðл¯

Ïë±ØÈȰ®ÓÎÏ·µÄͬѧСʱºò¶¼»ÃÏë¹ýÒªÊÇ×Ô¼º»á·ÖÉíÖ®Êõ£¬¾ÍÄÜÒ»±ß´òÓÎÏ·Ò»±ßÉÏ¿ÎÁË¡£

¿ÉϧÏÖʵÖв¢Ã»ÓÐÕâ¸ö¼¼Êõ£¬ÄãҪôֻÓÐÀÏÀÏʵʵµÄÉϿΣ¬ÒªÃ´¾ÍÖ»ÓÐÌÓ¿ÎÈ¥´òÓÎÏ·ÁË¡£

ËäÈ»ÔÚÏÖʵÖÐÎÒÃÇÎÞ·¨ÊµÏÖ·ÖÉíÕâÑùµÄ¼¼Êõ£¬µ«ÊÇÎÒÃÇ¿ÉÒÔÔÚ¼ÆËã»úÊÀ½çÖÐʵÏÖÕâÑùµÄÔ¸Íû¡£

¼ÆËã»úÖеķÖÉíÊõ

¼ÆËã»úÖеķÖÉíÊõ²»ÊÇÌìÉú¾ÍÓÐÁË¡£ÔÚ 1971 Äê£¬Ó¢ÌØ¶ûÍÆ³öµÄÈ«ÇòµÚÒ»¿ÅͨÓÃÐÍ΢´¦ÀíÆ÷ 4004£¬ÓÉ 2300 ¸ö¾§Ìå¹Ü¹¹³É¡£

µ±Ê±£¬¹«Ë¾µÄÁªºÏ´´Ê¼ÈËÖ®Ò»¸êµÇĦ¶û¾ÍÌá³ö´óÃû¶¦¶¦µÄ¡°Ä¦¶û¶¨ÂÉ¡±¡ª¡ªÃ¿¹ý 18 ¸öÔ£¬Ð¾Æ¬ÉÏ¿ÉÒÔ¼¯³ÉµÄ¾§Ìå¹ÜÊýÄ¿½«Ôö¼ÓÒ»±¶¡£

×î³õµÄÖ÷Ƶ 740KHz(ÿÃëÔËÐÐ 74 Íò´Î)£¬ÏÖÔÚ¹ýÁË¿ì 50 ÄêÁË£¬´ó¼ÒÈ¥ÂòµçÄÔµÄʱºò»á·¢ÏÖÏÖÔÚµÄÖ÷Ƶ¶¼ÄÜ´ïµ½ 4.0GHZÁË(ÿÃë 40 ÒÚ´Î)¡£

µ«ÊÇÖ÷ƵԽ¸ß´øÀ´µÄÊÕÒæÈ´ÊÇÔ½À´Ô½Ð¡£º

¾Ý²âË㣬Ö÷ƵÿÔö¼Ó 1G£¬¹¦ºÄ½«ÉÏÉý 25 Íߣ¬¶øÔÚоƬ¹¦ºÄ³¬¹ý 150 Íߺó£¬ÏÖÓеķçÀäÉ¢ÈÈϵͳ½«ÎÞ·¨Âú×ãÉ¢ÈȵÄÐèÒª¡£Óв¿·Ö CPU ¶¼¿ÉÒÔÓÃÀ´¼å¼¦µ°ÁË¡£

Á÷Ë®Ïß¹ý³¤£¬Ê¹µÃµ¥Î»ÆµÂÊЧÄܵÍÏ£¬Ô½´óµÄÖ÷ƵÆäʵÕûÌåÐÔÄÜ·´¶ø²»ÈçСµÄÖ÷Ƶ¡£

¸êµÇĦ¶ûÈÏΪĦ¶û¶¨ÂÉδÀ´ 10-20 Äê»áʧЧ¡£

ÔÚµ¥ºËÖ÷ƵÓöµ½Æ¿¾±µÄÇé¿öÏ£¬¶àºË CPU Ó¦Ô˶øÉú£¬²»½öÌáÉýÁËÐÔÄÜ£¬²¢ÇÒ½µµÍÁ˹¦ºÄ¡£

ËùÒÔ¶àºË CPU Öð½¥³ÉΪÏÖÔÚÊг¡µÄÖ÷Á÷£¬ÕâÑùÈÃÎÒÃǵĶàÏ̱߳à³ÌÒ²¸ü¼ÓµÄÈÝÒס£

˵µ½Á˶àºË CPU ¾ÍÒ»¶¨ÒªËµ GPU£¬´ó¼Ò¿ÉÄܶÔÕâ¸ö±È½ÏİÉú£¬µ«ÊÇһ˵µ½ÏÔ¿¨¾Í¿Ï¶¨²»Ä°Éú£¬±ÊÕ߸ã¹ýÒ»¶Îʱ¼äµÄ CUDA ±à³Ì£¬ÎÒ²ÅÒâʶµ½Õâ¸ö²ÅÊÇÕæÕýµÄ²¢ÐмÆËã¡£

´ó¼Ò¶¼ÖªµÀͼƬÏñËØµã°É£¬±ÈÈç 1920*1080 µÄͼƬÓÐ 210 Íò¸öÏñËØµã£¬Èç¹ûÏëÒª°ÑÒ»ÕÅͼƬµÄÿ¸öÏñËØµã¶¼½øÐÐת»»Ò»Ï£¬ÄÇÔÚÎÒÃÇ Java ÀïÃæ¿ÉÄܾÍҪѭ»·±éÀú 210 Íò´Î¡£

¾ÍËãÎÒÃÇÓöàÏß³Ì 8 ºË CPU£¬ÄÇÒ²µÃÑ­»·¼¸Ê®Íò´Î¡£µ«ÊÇÈç¹ûʹÓà Cuda£¬×î¶à¿ÉÒÔ 365535*512 = 100661760(Ò»ÒÚ)¸öÏ̲߳¢ÐÐÖ´ÐУ¬¾ÍÕâÖÖ¼¶±ðµÄͼƬÄÇÒ²ÊÇÂíÉÏ´¦ÀíÍê³É¡£

µ«ÊÇ Cuda Ò»°ãÊʺÏÓÚͼƬÕâÖÖ£¬ÓдóÁ¿µÄÏñËØµãÐèҪͬʱ´¦Àí£¬µ«ÊÇÖ¸ÁºÜÉÙËùÒÔÂß¼­²»ÄÜÌ«¸´ÔÓ¡£

Ó¦ÓÃÖеIJ¢ÐÐ

һ˵ÆðÈÃÄãµÄ·þÎñ¸ßÐÔÄܵÄÊֶΣ¬ÄÇôÒì²½»¯£¬²¢Ðл¯ÕâЩ¿Ï¶¨»áµÚһʱ¼äÔÚÄãÄÔº£ÖÐÏÔÏÖ³öÀ´£¬²¢Ðл¯¿ÉÒÔÓÃÀ´ÅäºÏÒì²½»¯£¬Ò²¿ÉÒÔÓÃÀ´µ¥¶À×öÓÅ»¯¡£

ÎÒÃÇ¿ÉÒÔÏëÏëÓÐÕâôһ¸öÐèÇó,ÔÚÄãÏÂÍâÂô¶©µ¥µÄʱºò£¬Õâ±Ê¶©µ¥¿ÉÄÜ»¹ÐèÒª²éÓû§ÐÅÏ¢£¬ÕÛ¿ÛÐÅÏ¢£¬É̼ÒÐÅÏ¢£¬²ËÆ·ÐÅÏ¢µÈ¡£

ÓÃͬ²½µÄ·½Ê½µ÷Óã¬ÈçÏÂͼËùʾ£º

ÉèÏëÒ»ÏÂÕâ 5 ¸ö²éѯ·þÎñ£¬Æ½¾ùÿ´ÎÏûºÄ 50ms£¬ÄÇô±¾´Îµ÷ÓÃÖÁÉÙÊÇ 250ms£¬ÎÒÃÇϸÏëһϣ¬ÕâÎå¸ö·þÎñÆäʵ²¢Ã»ÓÐÈκεÄÒÀÀµ£¬Ë­ÏÈ»ñȡ˭ºó»ñÈ¡¶¼¿ÉÒÔ¡£

ÄÇôÎÒÃÇ¿ÉÒÔÏëÏ룬ÊÇ·ñ¿ÉÒÔÓöàÖØÓ°·ÖÉíÖ®Êõ£¬Í¬Ê±»ñÈ¡ÕâÎå¸ö·þÎñµÄÐÅÏ¢ÄØ?

ÓÅ»¯ÈçÏ£º

½«ÕâÎå¸ö²éѯ·þÎñ²¢Ðвéѯ£¬ÔÚÀíÏëÇé¿öÏ¿ÉÒÔÓÅ»¯ÖÁ 50ms¡£µ±È»ËµÆðÀ´¼òµ¥£¬ÎÒÃÇÕæÕýÈçºÎÂ䵨Ĩ?

CountDownLatch/Phaser

CountDownLatch ºÍ Phaser ÊÇ JDK ÌṩµÄͬ²½¹¤¾ßÀà¡£Phaser ÊÇ 1.7 °æ±¾Ö®ºóÌṩµÄ¹¤¾ßÀà¡£¶ø CountDownLatch ÊÇ 1.5 °æ±¾Ö®ºóÌṩµÄ¹¤¾ßÀà¡£

ÕâÀï¼òµ¥½éÉÜһϠCountDownLatch£¬¿ÉÒÔ½«Æä¿´³ÉÊÇÒ»¸ö¼ÆÊýÆ÷£¬await()·½·¨¿ÉÒÔ×èÈûÖÁ³¬Ê±»òÕß¼ÆÊýÆ÷¼õÖÁ 0£¬ÆäËûÏ̵߳±Íê³É×Ô¼ºÄ¿±êµÄʱºò¿ÉÒÔ¼õÉÙ 1£¬ÀûÓÃÕâ¸ö»úÖÆÎÒÃÇ¿ÉÒÔÓÃÀ´×ö²¢·¢¡£

¿ÉÒÔÓÃÈçϵĴúÂëʵÏÖÎÒÃÇÉÏÃæµÄ϶©µ¥µÄÐèÇó£º

public class CountDownTask {
private static final int CORE_POOL_SIZE = 4;
private static final int MAX_POOL_SIZE = 12;
private static final long KEEP_ALIVE_TIME = 5L;
private final static int QUEUE_SIZE = 1600;

protected final static ExecutorService THREAD_POOL = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE,
KEEP_ALIVE_TIME, TimeUnit.SECONDS, new LinkedBlockingQueue<>(QUEUE_SIZE));
public static void main(String[] args) throws InterruptedException {
// н¨Ò»¸öΪ5µÄ¼ÆÊýÆ÷
CountDownLatch countDownLatch = new CountDownLatch(5);
OrderInfo orderInfo = new OrderInfo();
THREAD_POOL.execute(() -> {
System.out.println("µ±Ç°ÈÎÎñCustomer,Ïß³ÌÃû×ÖΪ:" + Thread.currentThread().getName());
orderInfo.setCustomerInfo(new CustomerInfo());
countDownLatch.countDown();
});
THREAD_POOL.execute(() -> {
System.out.println("µ±Ç°ÈÎÎñDiscount,Ïß³ÌÃû×ÖΪ:" + Thread.currentThread().getName());
orderInfo.setDiscountInfo(new DiscountInfo());
countDownLatch.countDown();
});
THREAD_POOL.execute(() -> {
System.out.println("µ±Ç°ÈÎÎñFood,Ïß³ÌÃû×ÖΪ:" + Thread.currentThread().getName());
orderInfo.setFoodListInfo(new FoodListInfo());
countDownLatch.countDown();
});
THREAD_POOL.execute(() -> {
System.out.println("µ±Ç°ÈÎÎñTenant,Ïß³ÌÃû×ÖΪ:" + Thread.currentThread().getName());
orderInfo.setTenantInfo(new TenantInfo());
countDownLatch.countDown();
});
THREAD_POOL.execute(() -> {
System.out.println("µ±Ç°ÈÎÎñOtherInfo,Ïß³ÌÃû×ÖΪ:" + Thread.currentThread().getName());
orderInfo.setOtherInfo(new OtherInfo());
countDownLatch.countDown();
});
countDownLatch.await(1, TimeUnit.SECONDS);
System.out.println("Ö÷Ị̈߳º"+ Thread.currentThread().getName());
}
}

½¨Á¢Ò»¸öÏ̳߳Ø(¾ßÌåÅäÖøù¾Ý¾ßÌåÒµÎñ£¬¾ßÌå»úÆ÷ÅäÖÃ)£¬½øÐв¢·¢µÄÖ´ÐÐÎÒÃǵÄÈÎÎñ(Éú³ÉÓû§ÐÅÏ¢£¬²ËÆ·ÐÅÏ¢µÈ)£¬×îºóÀûÓà await ·½·¨×èÈûµÈ´ý½á¹û³É¹¦·µ»Ø¡£

CompletableFuture

ÏàП÷λͬѧÒѾ­·¢ÏÖ£¬CountDownLatch ËäÈ»ÄÜʵÏÖÎÒÃÇÐèÒªÂú×ãµÄ¹¦Äܵ«ÊÇÆäÈÔÈ»ÓиöÎÊÌâÊÇ£¬ÎÒÃǵÄÒµÎñ´úÂëÐèÒªñîºÏ CountDownLatch µÄ´úÂë¡£

±ÈÈçÔÚÎÒÃÇ»ñÈ¡Óû§ÐÅÏ¢Ö®ºó£¬ÎÒÃÇ»áÖ´ÐÐ countDownLatch.countDown()£¬ºÜÃ÷ÏÔÎÒÃǵÄÒµÎñ´úÂëÏÔÈ»²»Ó¦¸Ã¹ØÐÄÕâÒ»²¿·ÖÂß¼­£¬²¢ÇÒÔÚ¿ª·¢µÄ¹ý³ÌÖÐÍòһд©ÁË£¬ÄÇÎÒÃÇµÄ await ·½·¨½«Ö»»á±»¸÷ÖÖÒì³£»½ÐÑ¡£

ËùÒÔÔÚ JDK 1.8 ÖÐÌṩÁËÒ»¸öÀà CompletableFuture£¬ËüÊÇÒ»¸ö¶à¹¦ÄܵķÇ×èÈûµÄ Future¡£(ʲôÊÇ Future£ºÓÃÀ´´ú±íÒì²½½á¹û£¬²¢ÇÒÌṩÁ˼ì²é¼ÆËãÍê³É£¬µÈ´ýÍê³É£¬¼ìË÷½á¹ûÍê³ÉµÈ·½·¨¡£)

ÎÒÃǽ«Ã¿¸öÈÎÎñµÄ¼ÆËãÍê³ÉµÄ½á¹û¶¼Óà CompletableFuture À´±íʾ£¬ÀûÓà CompletableFuture.allOf »ã¾Û³ÉÒ»¸ö´óµÄ CompletableFuture£¬ÄÇôÀûÓà get()·½·¨¾Í¿ÉÒÔ×èÈû¡£

public class CompletableFutureParallel {
private static final int CORE_POOL_SIZE = 4;
private static final int MAX_POOL_SIZE = 12;
private static final long KEEP_ALIVE_TIME = 5L;
private final static int QUEUE_SIZE = 1600;

protected final static ExecutorService THREAD_POOL = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE,
KEEP_ALIVE_TIME, TimeUnit.SECONDS, new LinkedBlockingQueue<>(QUEUE_SIZE));
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
OrderInfo orderInfo = new OrderInfo();
//CompletableFuture µÄList
List<CompletableFuture> futures = new ArrayList<>();
futures.add(CompletableFuture.runAsync(() -> {
System.out.println("µ±Ç°ÈÎÎñCustomer,Ïß³ÌÃû×ÖΪ:" + Thread.currentThread().getName());
orderInfo.setCustomerInfo(new CustomerInfo());
}, THREAD_POOL));
futures.add(CompletableFuture.runAsync(() -> {
System.out.println("µ±Ç°ÈÎÎñDiscount,Ïß³ÌÃû×ÖΪ:" + Thread.currentThread().getName());
orderInfo.setDiscountInfo(new DiscountInfo());
}, THREAD_POOL));
futures.add( CompletableFuture.runAsync(() -> {
System.out.println("µ±Ç°ÈÎÎñFood,Ïß³ÌÃû×ÖΪ:" + Thread.currentThread().getName());
orderInfo.setFoodListInfo(new FoodListInfo());
}, THREAD_POOL));
futures.add(CompletableFuture.runAsync(() -> {
System.out.println("µ±Ç°ÈÎÎñOther,Ïß³ÌÃû×ÖΪ:" + Thread.currentThread().getName());
orderInfo.setOtherInfo(new OtherInfo());
}, THREAD_POOL));
CompletableFuture allDoneFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
allDoneFuture.get(10, TimeUnit.SECONDS);
System.out.println(orderInfo);
}
}

¿ÉÒÔ¿´¼ûÎÒÃÇʹÓà CompletableFuture ÄܺܿìµÄÍê³ÉÐèÇ󣬵±È»Õ⻹²»¹»¡£

Fork/Join

ÎÒÃÇÉÏÃæÓà CompletableFuture Íê³ÉÁ˶Զà×éÈÎÎñ²¢ÐÐÖ´ÐУ¬µ«ÊÇËüÒÀÈ»ÊÇÒÀÀµÎÒÃǵÄÏ̳߳ء£

ÔÚÎÒÃǵÄÏ̳߳ØÖÐʹÓõÄÊÇ×èÈû¶ÓÁУ¬Ò²¾ÍÊǵ±ÎÒÃÇij¸öÏß³ÌÖ´ÐÐÍêÈÎÎñµÄʱºòÐèҪͨ¹ýÕâ¸ö×èÈû¶ÓÁнøÐУ¬ÄÇô¿Ï¶¨»á·¢Éú¾ºÕù£¬ËùÒÔÔÚ JDK 1.7 ÖÐÌṩÁË ForkJoinTask ºÍ ForkJoinPool¡£

ForkJoinPool ÖÐÿ¸öÏ̶߳¼ÓÐ×Ô¼ºµÄ¹¤×÷¶ÓÁУ¬²¢ÇÒ²ÉÓà Work-Steal Ëã·¨·ÀÖ¹Ï̼߳¢¶ö¡£

Worker Ïß³ÌÓà LIFO µÄ·½·¨È¡³öÈÎÎñ£¬µ«ÊÇ»áÓà FIFO µÄ·½·¨È¥ÍµÈ¡±ðÈ˶ÓÁеÄÈÎÎñ£¬ÕâÑù¾Í¼õÉÙÁËËøµÄ³åÍ»¡£

ÍøÉÏÕâ¸ö¿ò¼ÜµÄÀý×Ӻܶ࣬ÎÒÃÇ¿´¿´ÈçºÎʹÓôúÂëÍê³ÉÎÒÃÇÉÏÃæµÄ϶©µ¥ÐèÇó£º

public class OrderTask extends RecursiveTask<OrderInfo> {
@Override
protected OrderInfo compute() {
System.out.println("Ö´ÐÐ"+ this.getClass().getSimpleName() + "Ïß³ÌÃû×ÖΪ:" + Thread.currentThread().getName());
// ¶¨ÒåÆäËûÎåÖÖ²¢ÐÐTasK
CustomerTask customerTask = new CustomerTask();
TenantTask tenantTask = new TenantTask();
DiscountTask discountTask = new DiscountTask();
FoodTask foodTask = new FoodTask();
OtherTask otherTask = new OtherTask();
invokeAll(customerTask, tenantTask, discountTask, foodTask, otherTask);
OrderInfo orderInfo = new OrderInfo(customerTask.join(), tenantTask.join(), discountTask.join(), foodTask.join(), otherTask.join());
return orderInfo;
}
public static void main(String[] args) {
ForkJoinPool forkJoinPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors() -1 );
System.out.println(forkJoinPool.invoke(new OrderTask()));
}
}
class CustomerTask extends RecursiveTask<CustomerInfo>{

@Override
protected CustomerInfo compute() {
System.out.println("Ö´ÐÐ"+ this.getClass().getSimpleName() + "Ïß³ÌÃû×ÖΪ:" + Thread.currentThread().getName());
return new CustomerInfo();
}
}
class TenantTask extends RecursiveTask<TenantInfo>{

@Override
protected TenantInfo compute() {
System.out.println("Ö´ÐÐ"+ this.getClass().getSimpleName() + "Ïß³ÌÃû×ÖΪ:" + Thread.currentThread().getName());
return new TenantInfo();
}
}
class DiscountTask extends RecursiveTask<DiscountInfo>{

@Override
protected DiscountInfo compute() {
System.out.println("Ö´ÐÐ"+ this.getClass().getSimpleName() + "Ïß³ÌÃû×ÖΪ:" + Thread.currentThread().getName());
return new DiscountInfo();
}
}
class FoodTask extends RecursiveTask<FoodListInfo>{

@Override
protected FoodListInfo compute() {
System.out.println("Ö´ÐÐ"+ this.getClass().getSimpleName() + "Ïß³ÌÃû×ÖΪ:" + Thread.currentThread().getName());
return new FoodListInfo();
}
}
class OtherTask extends RecursiveTask<OtherInfo>{

@Override
protected OtherInfo compute() {
System.out.println("Ö´ÐÐ"+ this.getClass().getSimpleName() + "Ïß³ÌÃû×ÖΪ:" + Thread.currentThread().getName());
return new OtherInfo();
}
}

ÎÒÃǶ¨ÒåÒ»¸ö Order Task ²¢ÇÒ¶¨ÒåÎå¸ö»ñÈ¡ÐÅÏ¢µÄÈÎÎñ£¬ÔÚ Compute Öзֱð Fork Ö´ÐÐÕâÎå¸öÈÎÎñ£¬×îºóÔÚ½«ÕâÎå¸öÈÎÎñµÄ½á¹ûͨ¹ý Join »ñµÃ£¬×îºóÍê³ÉÎÒÃǵIJ¢Ðл¯µÄÐèÇó¡£

parallelStream

ÔÚ JDK 1.8 ÖÐÌṩÁ˲¢ÐÐÁ÷µÄ API£¬µ±ÎÒÃÇʹÓü¯ºÏµÄʱºòÄܺܺõĽøÐв¢Ðд¦Àí¡£

ÏÂÃæ¾ÙÁËÒ»¸ö¼òµ¥µÄÀý×Ó´Ó 1 ¼Óµ½ 100£º

public class ParallelStream {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 1; i <= 100; i++) {
list.add(i);
}
LongAdder sum = new LongAdder();
list.parallelStream().forEach(integer -> {
// System.out.println("µ±Ç°Ïß³Ì" + Thread.currentThread().getName());
sum.add(integer);
});
System.out.println(sum);
}
}

parallelStream ÖеײãʹÓõÄÄÇÒ»Ì×Ò²ÊÇ Fork/Join µÄÄÇÒ»Ì×£¬Ä¬ÈϵIJ¢·¢³Ì¶ÈÊÇ¿ÉÓà CPU Êý -1¡£

·ÖƬ

¿ÉÒÔÏëÏóÓÐÕâôһ¸öÐèÇó£¬Ã¿Ì춨ʱ¶Ô ID ÔÚij¸ö·¶Î§Ö®¼äµÄÓû§·¢È¯£¬±ÈÈçÕâ¸ö·¶Î§Ö®¼äµÄÓû§Óм¸°ÙÍò£¬Èç¹û¸øÒ»Ì¨»úÆ÷·¢µÄ»°£¬¿ÉÄÜÈ«²¿·¢ÍêÐèÒªºÜ¾ÃµÄʱ¼ä¡£

ËùÒÔ·Ö²¼Ê½µ÷¶È¿ò¼Ü±ÈÈ磺elastic-job ¶¼ÌṩÁË·ÖÆ¬µÄ¹¦ÄÜ£¬±ÈÈçÄãÓà 50 ̨»úÆ÷£¬ÄÇô id%50 = 0 µÄÔÚµÚ 0 ̨»úÆ÷ÉÏ;=1 µÄÔÚµÚ 1 ̨»úÆ÷ÉÏ·¢È¯£¬ÄÇôÎÒÃǵÄÖ´ÐÐʱ¼äÆäʵ¾Í·Ö̯µ½Á˲»Í¬µÄ»úÆ÷ÉÏÁË¡£

²¢Ðл¯×¢ÒâÊÂÏî

Ḭ̈߳²È«£ºÔÚ parallelStream ÖÐÎÒÃÇÁоٵĴúÂëÖÐʹÓõÄÊÇ LongAdder£¬²¢Ã»ÓÐÖ±½ÓʹÓÃÎÒÃÇµÄ Integer ºÍ Long£¬Õâ¸öÊÇÒòΪÔÚ¶àÏ̻߳·¾³Ï Integer ºÍ Long Ï̲߳»°²È«¡£ËùÒÔḬ̈߳²È«ÎÒÃÇÐèÒªÌØ±ð×¢Òâ¡£

ºÏÀí²ÎÊýÅäÖ㺿ÉÒÔ¿´¼ûÎÒÃÇÐèÒªÅäÖõIJÎÊý±È½Ï¶à£¬±ÈÈçÎÒÃǵÄÏ̳߳صĴóС£¬µÈ´ý¶ÓÁдóС£¬²¢ÐжȴóСÒÔ¼°ÎÒÃǵĵȴý³¬Ê±Ê±¼äµÈµÈ¡£

ÎÒÃǶ¼ÐèÒª¸ù¾Ý×Ô¼ºµÄÒµÎñ²»¶ÏµÄµ÷ÓÅ·ÀÖ¹³öÏÖ¶ÓÁв»¹»ÓûòÕß³¬Ê±Ê±¼ä²»ºÏÀíµÈµÈ¡£

ÉÏÃæ½éÉÜÁËʲôÊDz¢Ðл¯£¬²¢Ðл¯µÄ¸÷ÖÖÀúÊ·£¬ÔÚ Java ÖÐÈçºÎʵÏÖ²¢Ðл¯£¬ÒÔ¼°²¢Ðл¯µÄ×¢ÒâÊÂÏϣÍû´ó¼Ò¶Ô²¢Ðл¯Óиö±È½ÏÈ«ÃæµÄÈÏʶ¡£

×îºó¸ø´ó¼ÒÌá¸öÁ½¸öСÎÊÌ⣺

ÔÚÎÒÃDz¢Ðл¯µ±ÖÐÓÐij¸öÈÎÎñÈç¹ûij¸öÈÎÎñ³öÏÖÁËÒì³£Ó¦¸ÃÔõô°ì?

ÔÚÎÒÃDz¢Ðл¯µ±ÖÐÓÐij¸öÈÎÎñµÄÐÅÏ¢²¢²»ÊÇÇ¿ÒÀÀµ£¬Ò²¾ÍÊÇÈç¹û³öÏÖÁËÎÊÌâÕⲿ·ÖÐÅÏ¢ÎÒÃÇÒ²¿ÉÒÔ²»ÐèÒª£¬µ±²¢Ðл¯µÄʱºò£¬ÕâÖÖÈÎÎñ³öÏÖÁËÒì³£Ó¦¸ÃÔõô°ì?

   
6326 ´Îä¯ÀÀ       30
Ïà¹ØÎÄÕÂ

ÆóÒµ¼Ü¹¹¡¢TOGAFÓëArchiMate¸ÅÀÀ
¼Ü¹¹Ê¦Ö®Â·-ÈçºÎ×öºÃÒµÎñ½¨Ä££¿
´óÐÍÍøÕ¾µçÉÌÍøÕ¾¼Ü¹¹°¸ÀýºÍ¼¼Êõ¼Ü¹¹µÄʾÀý
ÍêÕûµÄArchimateÊÓµãÖ¸ÄÏ£¨°üÀ¨Ê¾Àý£©
Ïà¹ØÎĵµ

Êý¾ÝÖÐ̨¼¼Êõ¼Ü¹¹·½·¨ÂÛÓëʵ¼ù
ÊÊÓÃArchiMate¡¢EA ºÍ iSpace½øÐÐÆóÒµ¼Ü¹¹½¨Ä£
ZachmanÆóÒµ¼Ü¹¹¿ò¼Ü¼ò½é
ÆóÒµ¼Ü¹¹ÈÃSOAÂ䵨
Ïà¹Ø¿Î³Ì

ÔÆÆ½Ì¨Óë΢·þÎñ¼Ü¹¹Éè¼Æ
ÖÐ̨սÂÔ¡¢ÖÐ̨½¨ÉèÓëÊý×ÖÉÌÒµ
ÒÚ¼¶Óû§¸ß²¢·¢¡¢¸ß¿ÉÓÃϵͳ¼Ü¹¹
¸ß¿ÉÓ÷ֲ¼Ê½¼Ü¹¹Éè¼ÆÓëʵ¼ù