【B2B研发商城】 【加入收藏】 【设为首页】 【进入论坛】 【站点地图】

你的位置:中国研发网 >> 技术文章 >> web开发 >> Java >> 详细内容 在线投稿

java多线程技术精要

热度151票  浏览24次 【共0条评论】【我要评论 时间:2010年5月07日 15:35

试想一下以下经常碰到的业务环境的解决方案,比如未联网的*****系统:

 

数据集中部署在地级市(如宁波,杭州,温州等),各个地级市数据并不联网
业务目标:查询全国内范围的满足查询条件的数据记录


解决方案:利用地级市提供的查询接口(可能是Web Service为主)开始多线程查询,并异步展现查询结果


开发步骤:
如果使用异步Web Service,可以利用Axis2,核心代码如下:
Java代码
QName qname = new QName(namespace, operateName);  
        RPCServiceClient client = new RPCServiceClient();  
        Options options = new Options();  
        options.setTo(new EndpointReference(srvcUrl));  
        options.setAction("urn:" + operateName);  
        client.setOptions(options);  
        client.invokeNonBlocking(qname, param, new AxisCallback() {  
                public void onMessage(MessageContext mc)              {  
                        //回调处理代码  
                    }  
                    public void onFault(MessageContext messageContext) {  
                    }  
                    public void onError(Exception e) {  
                        e.printStackTrace();  
                    }  
                    public void onComplete() {  
                    }  
        }); 

QName qname = new QName(namespace, operateName);
  RPCServiceClient client = new RPCServiceClient();
  Options options = new Options();
  options.setTo(new EndpointReference(srvcUrl));
  options.setAction("urn:" + operateName);
  client.setOptions(options);
  client.invokeNonBlocking(qname, param, new AxisCallback() {
    public void onMessage(MessageContext mc)              {
      //回调处理代码
     }
     public void onFault(MessageContext messageContext) {
     }
     public void onError(Exception e) {
      e.printStackTrace();
     }
     public void onComplete() {
     }
  });如何利用线程池管理多线程,核心代码如下:
Java代码
public List invokeAll(List<TraversalProvince> tasks, long timeout) {  
        List nodes = new ArrayList(tasks.size());  
        try {  
            List<Future<CityResult>> futures = null;  
            if (timeout < 0) {  
                futures = executorService.invokeAll(tasks);  
            } else {  
                futures = executorService.invokeAll(tasks, timeout, TimeUnit.MILLISECONDS);  
            }  
            for (Future future : futures) {  
                try {  
                    nodes.add(future.get());  
                } catch (ExecutionException e) {  
                    e.printStackTrace();  
                }  
            }  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        return nodes;  
    } 

public List invokeAll(List<TraversalProvince> tasks, long timeout) {
        List nodes = new ArrayList(tasks.size());
        try {
            List<Future<CityResult>> futures = null;
            if (timeout < 0) {
                futures = executorService.invokeAll(tasks);
            } else {
                futures = executorService.invokeAll(tasks, timeout, TimeUnit.MILLISECONDS);
            }
            for (Future future : futures) {
                try {
                    nodes.add(future.get());
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return nodes;
    }
对结果产生的回调处理:
Java代码
String taskno = StrCharUtil.formatNullStr(request.getParameter("taskno"));  
String callback = StrCharUtil.formatNullStr(request.getParameter("callback"));  
for(int i=0;i<10;i++){  
    Thread.sleep(1000);//10秒内未获取到数据表示失败  
    String res = StrCharUtil.formatNullStr(cacheTask.get(taskno));  
    if(!res.equals("")){  
        if(callback.equals("")){  
            out.println(res);  
        }else{  
            out.println(callback+"("+res+")");  
        }  
        return;  
    }  
}  
out.println("超时(timeout)"); 

String taskno = StrCharUtil.formatNullStr(request.getParameter("taskno"));
String callback = StrCharUtil.formatNullStr(request.getParameter("callback"));
for(int i=0;i<10;i++){
 Thread.sleep(1000);//10秒内未获取到数据表示失败
 String res = StrCharUtil.formatNullStr(cacheTask.get(taskno));
 if(!res.equals("")){
  if(callback.equals("")){
   out.println(res);
  }else{
   out.println(callback+"("+res+")");
  }
  return;
 }
}
out.println("超时(timeout)");
 

以下是Log4J跟踪的运行效果:

 

Log4j代码
2010 五月 07 14:08:18 INFO  cn.aw.task.REHunt - [14:08:18]接收到新请求:reqid=030c95364050453987c6b9a597e80295id=1,type=null,mode=0,prov=zhejiang,city=ningbo,city=hangzhou,city=shaoxing,city=jinhua,city=zhoushan,prov=shanghai,city=putuo  
2010 五月 07 14:08:18 INFO  cn.aw.task.TraversalProvince - ================================线程: ningbo  开始处理...  
2010 五月 07 14:08:18 INFO  cn.aw.task.TraversalProvince - ================================线程: hangzhou  开始处理...  
2010 五月 07 14:08:18 INFO  cn.aw.task.TraversalProvince - ================================线程: shaoxing  开始处理...  
2010 五月 07 14:08:18 INFO  cn.aw.task.TraversalProvince - ================================线程: jinhua  开始处理...  
2010 五月 07 14:08:18 INFO  cn.aw.task.TraversalProvince - ================================线程: zhoushan  开始处理...  
2010 五月 07 14:08:18 INFO  cn.aw.task.TraversalProvince - ================================线程: putuo  开始处理...  
2010 五月 07 14:08:18 INFO  cn.aw.servlet.AjaxServlet - 任务缓存大小:0 
2010 五月 07 14:08:18 INFO  cn.aw.task.CityTask - endTask:ningbo  
2010 五月 07 14:08:18 INFO  cn.aw.task.CityTask - endTask:putuo  
2010 五月 07 14:08:19 INFO  cn.aw.task.CityTask - endTask:hangzhou  
2010 五月 07 14:08:19 INFO  cn.aw.task.CityTask - endTask:shaoxing  
2010 五月 07 14:08:19 INFO  cn.aw.task.CityTask - endTask:jinhua  
2010 五月 07 14:08:19 INFO  cn.aw.task.CityTask - 无法查询【zhoushan】的【1】信息,出错  
2010 五月 07 14:08:19 INFO  cn.aw.task.CityTask - endTask:zhoushan  
2010 五月 07 14:08:19 INFO  cn.aw.task.REHunt - 开始调用返回URL:http://localhost:8080/ws/ajax...  
2010 五月 07 14:08:19 INFO  cn.aw.servlet.AjaxServlet - 已缓存结果:030c95364050453987c6b9a597e80295 

2010 五月 07 14:08:18 INFO  cn.aw.task.REHunt - [14:08:18]接收到新请求:reqid=030c95364050453987c6b9a597e80295id=1,type=null,mode=0,prov=zhejiang,city=ningbo,city=hangzhou,city=shaoxing,city=jinhua,city=zhoushan,prov=shanghai,city=putuo
2010 五月 07 14:08:18 INFO  cn.aw.task.TraversalProvince - ================================线程: ningbo  开始处理...
2010 五月 07 14:08:18 INFO  cn.aw.task.TraversalProvince - ================================线程: hangzhou  开始处理...
2010 五月 07 14:08:18 INFO  cn.aw.task.TraversalProvince - ================================线程: shaoxing  开始处理...
2010 五月 07 14:08:18 INFO  cn.aw.task.TraversalProvince - ================================线程: jinhua  开始处理...
2010 五月 07 14:08:18 INFO  cn.aw.task.TraversalProvince - ================================线程: zhoushan  开始处理...
2010 五月 07 14:08:18 INFO  cn.aw.task.TraversalProvince - ================================线程: putuo  开始处理...
2010 五月 07 14:08:18 INFO  cn.aw.servlet.AjaxServlet - 任务缓存大小:0
2010 五月 07 14:08:18 INFO  cn.aw.task.CityTask - endTask:ningbo
2010 五月 07 14:08:18 INFO  cn.aw.task.CityTask - endTask:putuo
2010 五月 07 14:08:19 INFO  cn.aw.task.CityTask - endTask:hangzhou
2010 五月 07 14:08:19 INFO  cn.aw.task.CityTask - endTask:shaoxing
2010 五月 07 14:08:19 INFO  cn.aw.task.CityTask - endTask:jinhua
2010 五月 07 14:08:19 INFO  cn.aw.task.CityTask - 无法查询【zhoushan】的【1】信息,出错
2010 五月 07 14:08:19 INFO  cn.aw.task.CityTask - endTask:zhoushan
2010 五月 07 14:08:19 INFO  cn.aw.task.REHunt - 开始调用返回URL:http://localhost:8080/ws/ajax...
2010 五月 07 14:08:19 INFO  cn.aw.servlet.AjaxServlet - 已缓存结果:030c95364050453987c6b9a597e80295如果你有更好的思路,欢迎探讨,主要解决查询效率问题和并发问题!

 

TAG: Java java
顶:4 踩:8
对本文中的事件或人物打分:
当前平均分:-0.78 (49次打分)
对本篇资讯内容的质量打分:
当前平均分:0.6 (50次打分)
【已经有40人表态】
5票
感动
3票
路过
3票
高兴
4票
难过
4票
搞笑
6票
愤怒
8票
无聊
7票
同情
上一篇 下一篇
发表评论

网友评论仅供网友表达个人看法,并不表明本网同意其观点或证实其描述。

查看全部回复【已有0位网友发表了看法】