±à¼ÍƼö: |
±¾ÎÄÀ´×ÔÓÚ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¸öÈÎÎñµÄÐÅÏ¢²¢²»ÊÇÇ¿ÒÀÀµ£¬Ò²¾ÍÊÇÈç¹û³öÏÖÁËÎÊÌâÕⲿ·ÖÐÅÏ¢ÎÒÃÇÒ²¿ÉÒÔ²»ÐèÒª£¬µ±²¢Ðл¯µÄʱºò£¬ÕâÖÖÈÎÎñ³öÏÖÁËÒì³£Ó¦¸ÃÔõô°ì? |