java多线程检测可用IP

最近有一个问题进行系统性能优化的时候来到。解析分享给大家后,。

我们socket当建立连接,假设我们不能将计算机连接到指定的站点,那么这将导致系统卡socket的connect在此方法。

我们都知道socket它需要三次握手建立连接。计算机server发送消息头,server返回。这时候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<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);
	}

}



版权声明:本文博主原创文章,博客,未经同意不得转载。

posted @ 2015-09-14 11:29  zfyouxi  阅读(414)  评论(0编辑  收藏  举报