java多线程检测可用ip_java多线程检测可用IP

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

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

我们都知道socket建立连接需要三次握手,计算机向服务器发送消息头,服务器返回,这时候socket基本连接成功,但是如果连接

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

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

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

现在改成并行测试,开启多个线程测试,有可用的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;

/**

* 资源探测器,从一组资源中检测出一个可用的资源

*

* @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;

}

}

/**创建探测一个资源的子线程*/

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是启动一个服务端监听,大家可以自行实现,代码太多就不复制上去了

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(){

//创建一个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 resources = new ArrayList();

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);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值