程序员人生 网站导航

[置顶] java多线程检测可用IP

栏目:互联网时间:2014-11-12 08:52:45

最近做系统性能优化的时候遇到的1个问题,解决以后分享给大家。

我们通过socket建立连接的时候,如果我们计算机不能与指定的站点连接上,那末这将会致使系统卡在socket的connect这个方法上,

我们都知道socket建立连接需要3次握手,计算机向http://www.wfuyu.com/server/发送消息头,http://www.wfuyu.com/server/返回,这时候候socket基本连接成功,但是如果连接

不上的话这里会卡1个Timeout的时间,时间1到,方法返回失败,socket默许的timeout好像是20秒,

我们系统现在有1个从可用的ip列表里面检测出1个可用的ip,拿出来作为可用数据保存到内存。

之前我们是串行测试,1个不可用再去尝试下1个,这个操作将业务流程停止在这1步很长时间。

现在改成并行测试,开启多个线程测试,有可用的ip以后直接返回,这个检测操作的时间缩减到毫秒级,大大提升了系统性能。

具体代码以下:


资源接口:

package com.sunyard.frame.resource.base; /** * 可初始化的资源 * * @author zhangWei * @since 2014年10月29日 下午6:58:55 * @version zhw_1.1 */ public abstract class InitAble { /** * 初始化 * @return true 初始化成功 */ public abstract boolean init(); /** * 烧毁该资源,如关闭连接等 */ public abstract void destory(); }


探测器:
package com.sunyard.frame.resource; import java.util.List; import com.sunyard.frame.resource.base.InitAble; import com.sunyard.frame.thread.ThreadPool; import com.sunyard.frame.utils.ListUtils; /** * 资源探测器,从1组资源中检测出1个可用的资源 * * @author zhangWei * @since 2014年10月29日 下午7:00:45 * @version zhw_1.1 */ public class ResourceDetector { /**待检测的资源*/ private List<? extends InitAble> resources; /**创建该对象的线程*/ private Thread mainThread; /**探测结果*/ private InitAble result; /**用于并发探测可用资源的线程池,可以用java的ExecutorService代替*/ private ThreadPool pool = new ThreadPool(10); /**探测失败的记录数*/ private Integer failCount = 0; public ResourceDetector(List<? extends InitAble> resources) { super(); this.resources = resources; this.mainThread = Thread.currentThread(); } /** * 探测器开始探测可用的资源 * * @author zhangWei * @since 2014年10月29日 下午7:20:21 */ public InitAble detect(){ if(ListUtils.isNotEmpty(resources)){ for(InitAble i:resources){ pool.execute(createDetectTask(i)); } synchronized (mainThread) { try { mainThread.wait(); } catch (InterruptedException e) { } } return result; } else { return null; } } /**创建探测1个资源的子线程*/ private Runnable createDetectTask(final InitAble i){ return new Runnable() { @Override public void run() { try{ if(i.init()){ result = i; synchronized (mainThread) { mainThread.notify(); } } else { synchronized (failCount) { if(++failCount == resources.size()){ synchronized (mainThread) { mainThread.notify(); } } } } } finally { i.destory(); } } }; } }

测试类:

这里的 SocketDecorate是 InitAble的子类,ServerSocketProxy是启动1个服务端监听,大家可以自行实现,代码太多就不复制上去了


package test.resource; import java.io.IOException; import java.util.ArrayList; import java.util.List; import test.socket.ServerServiceImpl; import junit.framework.TestCase; import com.sunyard.frame.resource.ResourceDetector; import com.sunyard.frame.socket.client.SocketDecorate; import com.sunyard.frame.socket.server.ServerSocketProxy; public class TestResource extends TestCase { public void testDetect(){ //创建1个ServerSocket ServerSocketProxy ss; try { ss = new ServerSocketProxy(1000, ServerServiceImpl.class, true); ss.startServer(); } catch (IOException e) { } SocketDecorate d1 = new SocketDecorate("168.1.1.1", 1000); SocketDecorate d2 = new SocketDecorate("168.1.1.2", 1000); SocketDecorate d3 = new SocketDecorate("168.1.1.3", 1000); SocketDecorate d4 = new SocketDecorate("168.1.1.4", 1000); SocketDecorate d5 = new SocketDecorate("168.1.1.5", 1000); SocketDecorate d6 = new SocketDecorate("168.1.1.6", 1000); SocketDecorate d7 = new SocketDecorate("168.1.1.7", 1000); SocketDecorate d8 = new SocketDecorate("127.0.0.1", 1000); List<SocketDecorate> resources = new ArrayList<SocketDecorate>(); resources.add(d1); resources.add(d2); resources.add(d3); resources.add(d4); resources.add(d5); resources.add(d6); resources.add(d7); resources.add(d8); ResourceDetector detector = new ResourceDetector(resources); SocketDecorate s = (SocketDecorate) detector.detect(); System.out.println(s); } }



------分隔线----------------------------
------分隔线----------------------------

最新技术推荐