`
uniseraph
  • 浏览: 82520 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

开发了一个高性能memcached java client

阅读更多
用mina开发了一个memcached java client ,性能测试表现良好, 用我的t61做客户端测试,最高能到28000tps。
代码在:http://commons-client.googlecode.com/svn/trunk/,有兴趣的朋友可以看看。我准备把这个项目开源,后面还有不少优化余地,有兴趣的朋友请和我联系,呵呵。


前提条件
1 jdk1.6
2 安装maven
3 安装ant

编译: ant
运行测试程序:  ant run -Dip=....  -Dthread=100 -Drepeat=10000 -Dsize=2
ip: memcached server ip
thread : 测试线程数
repeat : 每个线程循环此处,每次10000次,每次有两个memcache调用
size:  连接数
可以在命令行中输入参数,也可以修改build.properties中的默认参数


正在写文档,以后慢慢补上。

BTW, 有兴趣可以看看我blog的相关文档,http://uniseraph.iteye.com
分享到:
评论
30 楼 lxiaodao 2009-01-31  
简单看了一下源码,给后来要的朋友提醒:使用了jdk6里面String的str.getBytes(charset)方法,jdk5支持不了(我下载了jdk6后再看看)。顺便说一下,mina使用的是2.0版本。
不知道楼主可不可以改一下源码让JDK5也可以支持?
29 楼 liuye 2008-10-28  
uniseraph 写道
liuye 写道

get/set只能对字符串/字节操作,Object怎么办?另外,是不是没有考虑连接多个memcached服务器呀?


有数据了,再进行序列化和反序列化是很简单的。后续会包装一些接口。

连接多个服务器也是准备后续再做的,以现在的结构而言,支持起来很简单。

现在我正在考虑把单位时间内的多个get合并成一个gets操作,这样对系统性能提升应该有更大的帮助。



应该优先实现“连接多个memcached服务器”
28 楼 ThinkInJava 2008-10-27  
这个项目值得研究,我想稳定之后,将来应该是一个趋势了,理论很简单,就是内存越大,机器越快,期望能有更大的发展空间!
27 楼 fly_hyp 2008-10-27  
鼓励一下,之前我也尝试做过。
不过一个开源软件要取得成功,需要投入很多时间。还需要一些运作,和商业软件一样。
26 楼 uniseraph 2008-10-23  
贴一下测试代码:
public static void  main(String[] args){
//....
	MemcachedClient mc = new MemcachedClient(ip, port, size);

		CountDownLatch cdl = new CountDownLatch(thread);
		long t = System.currentTimeMillis();
		for (int i = 0; i < thread; i++) {
			new Thread(new TestRunnable(mc, i * 10000, cdl, repeat)).start();
		}

		try {
			cdl.await();
		} catch (InterruptedException e) {

		}

		long all = 2 * thread * repeat;
		long usingtime = (System.currentTimeMillis() - t);
		log
				.info(String
						.format(
								"thread num=%d, repeat=%d,size=%d, all=%d ,velocity=%d , using time:%d",
								thread, repeat, size, all, 1000 * all
										/ usingtime, usingtime));

		mc.pool.close();
}


static private class TestRunnable implements Runnable {

		private MemcachedClient mc;
		private CountDownLatch cd;
		int repeat;
		int start;

		public TestRunnable(MemcachedClient mc, int start, CountDownLatch cdl,
				int repeat) {
			super();
			this.mc = mc;
			this.start = start;
			this.cd = cdl;
			this.repeat = repeat;

		}

		public void run() {

			for (int i = 0; i < repeat; i++) {

				String key = Integer.toString(i);
				mc.set(key, key.getBytes());
				byte[] value = mc.get(key);
				if (log.isInfoEnabled()) {
					String result = new String(value);
					if (!result.equals(key)) {
						log.info(String
								.format("key:%s->result:%s", key, result));
						throw new IllegalStateException();
					}
				}

			}

			cd.countDown();
			// if (log.isDebugEnabled())
			// log.debug(String.format("%s count down", Thread.currentThread()
			// .getName()));
		}

	}



基本算法是:启动100个线程,每个线程循环10000次,每次发送两个操作,一个set一个get。100个线程全部退出,则记时结束。
25 楼 uniseraph 2008-10-22  
liuye 写道
uniseraph 写道
liuye 写道

get/set只能对字符串/字节操作,Object怎么办?另外,是不是没有考虑连接多个memcached服务器呀?


有数据了,再进行序列化和反序列化是很简单的。后续会包装一些接口。

连接多个服务器也是准备后续再做的,以现在的结构而言,支持起来很简单。

现在我正在考虑把单位时间内的多个get合并成一个gets操作,这样对系统性能提升应该有更大的帮助。


根据你的set/get写了read/write方法,对Object进行读写,write方法好像正常,但read方法在运行GetReponse rsp = (GetReponse) pool.send(command, true)时出错。代码如下:

	public Object read(String key) {

		GetCommand command = new GetCommand();

		command.setValue(key);

		GetReponse rsp = (GetReponse) pool.send(command, true);

		if (rsp != null && rsp.isSuccess()) {
			byte[] result = rsp.getResult();
			try {
				return bytes2Object(result);
			} catch (Exception e) {
				log.error(e.getMessage());
				e.printStackTrace();
			}

		}
		return null;
	}

	public void write(String key, Serializable value) {
		byte[] bytes = null;
		try {
			bytes = object2Bytes(value);
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		if (bytes != null) {
			SetCommand setCommand = new SetCommand();
			setCommand.setKey(key);
			setCommand.setValue(bytes);
			SetReponse rsp = (SetReponse) pool.send(setCommand, true);
			if (rsp != null && rsp.isSuccess()) {
			}
		}
	}

	public static Object bytes2Object(byte[] objBytes) throws Exception {
		if (objBytes == null || objBytes.length == 0) {
			return null;
		}
		ByteArrayInputStream bi = new ByteArrayInputStream(objBytes);
		ObjectInputStream oi = new ObjectInputStream(bi);
		return oi.readObject();
	}

	public static byte[] object2Bytes(Serializable obj) throws Exception {
		if (obj == null) {
			return null;
		}
		ByteArrayOutputStream bo = new ByteArrayOutputStream();
		ObjectOutputStream oo = new ObjectOutputStream(bo);
		oo.writeObject(obj);
		return bo.toByteArray();
	}





问题已经解决,主要是新增加了一个基于IoBuffer的协议解析器NormalReponseDecoder,取消了原来基于TextLineDecoder的LinedReponseDecoder。到现在为止已经有三种协议解析方法了,回头再做个测试,比较一下三个的区别。


代码已经提交到https://commons-client.googlecode.com/svn/branches/0.1.1 ,暂时不提主干,稳定以后再说。

测试代码如下:
public class Test {

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		ByteArrayOutputStream bo = new ByteArrayOutputStream();
		ObjectOutputStream oo = new ObjectOutputStream(bo);
		oo.writeObject(new Example(1, "hello"));
		byte[]  buffer = bo.toByteArray();
		
		MemcachedClient  mc = new MemcachedClient("10.2.224.34",11211,2);
		 mc.set("aaa", buffer);
		 byte[] result = mc.get("aaa" );
		 
		 boolean b = Arrays.equals(buffer, result);
		System.out.println(b);
		 
	}

	private static class Example implements Serializable {
		private int age;
		private String desc;

		public Example(int age, String desc) {
			super();
			this.age = age;
			this.desc = desc;
		}

	}
}

24 楼 uniseraph 2008-10-22  
Externalizable以前用过,比serialize快得多,但是比较麻烦,会要求每个结构都去实现这个接口,如果消息种类太多,那么开发工作量会比较大。不利于上层应用开发。

其实对于我这个框架来说,不关心是怎么进行序列化/反序列化的,我暴露byte[]出来,如果你关心效率,那么你可以用Externalizable或者hessian的序列化/反序列化,如果你不关心,那么就可以用serialize或者json,总之这属于接口友好性的领域。对项目本身影响不大。
23 楼 movingboy 2008-10-22  
其实JDK还提供了另一个接口Externalizable,相比使用Serializable的性能应该有提高。不知道对你有没有什么帮助
22 楼 uniseraph 2008-10-22  
问题已经确定,在解析命令响应的时候使用了mina提供的TextLineDecoder,这东东可以把一个IoBuffer分成多个指定间隔符的字符串数组,而使用Serializable序列化的byte数组有些认为是特殊字符,无法识别成字符串。

多谢帮我发现问题,呵呵,所以说开源就是好!

不过我的初衷是觉得java自带的序列化/反序列化效率太低了,所以希望能够自己实现。不管怎么样,我使用TextLineDecoder还是太偷懒了,呵呵,回头改一下。

21 楼 uniseraph 2008-10-22  
liuye 写道

uniseraph 写道liuye 写道
get/set只能对字符串/字节操作,Object怎么办?另外,是不是没有考虑连接多个memcached服务器呀?


有数据了,再进行序列化和反序列化是很简单的。后续会包装一些接口。

连接多个服务器也是准备后续再做的,以现在的结构而言,支持起来很简单。

现在我正在考虑把单位时间内的多个get合并成一个gets操作,这样对系统性能提升应该有更大的帮助。

根据你的set/get写了read/write方法,对Object进行读写,write方法好像正常,但read方法在运行GetReponse rsp = (GetReponse) pool.send(command, true)时出错。代码如下:

Java代码 public&nbsp;Object&nbsp;read(String&nbsp;key)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetCommand&nbsp;command&nbsp;=&nbsp;new&nbsp;GetCommand();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;command.setValue(key);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetReponse&nbsp;rsp&nbsp;=&nbsp;(GetReponse)&nbsp;pool.send(command,&nbsp;true);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(rsp&nbsp;!=&nbsp;null&nbsp;&amp;&amp;&nbsp;rsp.isSuccess())&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[]&nbsp;result&nbsp;=&nbsp;rsp.getResult();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;bytes2Object(result);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(Exception&nbsp;e)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.error(e.getMessage());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;null;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;write(String&nbsp;key,&nbsp;Serializable&nbsp;value)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[]&nbsp;bytes&nbsp;=&nbsp;null;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bytes&nbsp;=&nbsp;object2Bytes(value);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(Exception&nbsp;e)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.error(e.getMessage());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(bytes&nbsp;!=&nbsp;null)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetCommand&nbsp;setCommand&nbsp;=&nbsp;new&nbsp;SetCommand();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setCommand.setKey(key);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setCommand.setValue(bytes);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetReponse&nbsp;rsp&nbsp;=&nbsp;(SetReponse)&nbsp;pool.send(setCommand,&nbsp;true);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(rsp&nbsp;!=&nbsp;null&nbsp;&amp;&amp;&nbsp;rsp.isSuccess())&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;Object&nbsp;bytes2Object(byte[]&nbsp;objBytes)&nbsp;throws&nbsp;Exception&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(objBytes&nbsp;==&nbsp;null&nbsp;||&nbsp;objBytes.length&nbsp;==&nbsp;0)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;null;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteArrayInputStream&nbsp;bi&nbsp;=&nbsp;new&nbsp;ByteArrayInputStream(objBytes);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObjectInputStream&nbsp;oi&nbsp;=&nbsp;new&nbsp;ObjectInputStream(bi);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;oi.readObject();&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;byte[]&nbsp;object2Bytes(Serializable&nbsp;obj)&nbsp;throws&nbsp;Exception&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(obj&nbsp;==&nbsp;null)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;null;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteArrayOutputStream&nbsp;bo&nbsp;=&nbsp;new&nbsp;ByteArrayOutputStream();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObjectOutputStream&nbsp;oo&nbsp;=&nbsp;new&nbsp;ObjectOutputStream(bo);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oo.writeObject(obj);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;bo.toByteArray();&nbsp;&nbsp;}&nbsp;&nbsp; public Object read(String key) {

GetCommand command = new GetCommand();

command.setValue(key);

GetReponse rsp = (GetReponse) pool.send(command, true);

if (rsp != null &amp;&amp; rsp.isSuccess()) {
byte[] result = rsp.getResult();
try {
return bytes2Object(result);
} catch (Exception e) {
log.error(e.getMessage());
e.printStackTrace();
}

}
return null;
}

public void write(String key, Serializable value) {
byte[] bytes = null;
try {
bytes = object2Bytes(value);
} catch (Exception e) {
log.error(e.getMessage());
e.printStackTrace();
}
if (bytes != null) {
SetCommand setCommand = new SetCommand();
setCommand.setKey(key);
setCommand.setValue(bytes);
SetReponse rsp = (SetReponse) pool.send(setCommand, true);
if (rsp != null &amp;&amp; rsp.isSuccess()) {
}
}
}

public static Object bytes2Object(byte[] objBytes) throws Exception {
if (objBytes == null || objBytes.length == 0) {
return null;
}
ByteArrayInputStream bi = new ByteArrayInputStream(objBytes);
ObjectInputStream oi = new ObjectInputStream(bi);
return oi.readObject();
}

public static byte[] object2Bytes(Serializable obj) throws Exception {
if (obj == null) {
return null;
}
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(obj);
return bo.toByteArray();
}





把错误信息发出来看看。
20 楼 liuye 2008-10-22  
uniseraph 写道
liuye 写道

get/set只能对字符串/字节操作,Object怎么办?另外,是不是没有考虑连接多个memcached服务器呀?


有数据了,再进行序列化和反序列化是很简单的。后续会包装一些接口。

连接多个服务器也是准备后续再做的,以现在的结构而言,支持起来很简单。

现在我正在考虑把单位时间内的多个get合并成一个gets操作,这样对系统性能提升应该有更大的帮助。


根据你的set/get写了read/write方法,对Object进行读写,write方法好像正常,但read方法在运行GetReponse rsp = (GetReponse) pool.send(command, true)时出错。代码如下:

	public Object read(String key) {

		GetCommand command = new GetCommand();

		command.setValue(key);

		GetReponse rsp = (GetReponse) pool.send(command, true);

		if (rsp != null && rsp.isSuccess()) {
			byte[] result = rsp.getResult();
			try {
				return bytes2Object(result);
			} catch (Exception e) {
				log.error(e.getMessage());
				e.printStackTrace();
			}

		}
		return null;
	}

	public void write(String key, Serializable value) {
		byte[] bytes = null;
		try {
			bytes = object2Bytes(value);
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		if (bytes != null) {
			SetCommand setCommand = new SetCommand();
			setCommand.setKey(key);
			setCommand.setValue(bytes);
			SetReponse rsp = (SetReponse) pool.send(setCommand, true);
			if (rsp != null && rsp.isSuccess()) {
			}
		}
	}

	public static Object bytes2Object(byte[] objBytes) throws Exception {
		if (objBytes == null || objBytes.length == 0) {
			return null;
		}
		ByteArrayInputStream bi = new ByteArrayInputStream(objBytes);
		ObjectInputStream oi = new ObjectInputStream(bi);
		return oi.readObject();
	}

	public static byte[] object2Bytes(Serializable obj) throws Exception {
		if (obj == null) {
			return null;
		}
		ByteArrayOutputStream bo = new ByteArrayOutputStream();
		ObjectOutputStream oo = new ObjectOutputStream(bo);
		oo.writeObject(obj);
		return bo.toByteArray();
	}

19 楼 uniseraph 2008-10-22  
其实之前也有不少朋友想用nio做memcached client,在javaeye的论坛上也有过相关的讨论。不过问题在于memcached的协议中没有流水号,而一般异步框架都是通过流水号实现命令异步到同步的映射。

这次我是分析了memcached的源码,发现memcached在同一个session,命令处理是依次完成的,所以才能解决这个问题。

有兴趣可以看一下 ,我blog上关于memcached通讯层次的问题。
18 楼 uniseraph 2008-10-22  
iso1600 写道

uniseraph 写道liuye 写道
get/set只能对字符串/字节操作,Object怎么办?另外,是不是没有考虑连接多个memcached服务器呀?


有数据了,再进行序列化和反序列化是很简单的。后续会包装一些接口。

连接多个服务器也是准备后续再做的,以现在的结构而言,支持起来很简单。

现在我正在考虑把单位时间内的多个get合并成一个gets操作,这样对系统性能提升应该有更大的帮助。

合并get可能会费力不讨好


这与场景以及合并算法相关,先尝试尝试。
17 楼 iso1600 2008-10-22  
uniseraph 写道
liuye 写道

get/set只能对字符串/字节操作,Object怎么办?另外,是不是没有考虑连接多个memcached服务器呀?


有数据了,再进行序列化和反序列化是很简单的。后续会包装一些接口。

连接多个服务器也是准备后续再做的,以现在的结构而言,支持起来很简单。

现在我正在考虑把单位时间内的多个get合并成一个gets操作,这样对系统性能提升应该有更大的帮助。


合并get可能会费力不讨好
16 楼 liuye 2008-10-22  
uniseraph 写道
liuye 写道

get/set只能对字符串/字节操作,Object怎么办?另外,是不是没有考虑连接多个memcached服务器呀?


有数据了,再进行序列化和反序列化是很简单的。后续会包装一些接口。

连接多个服务器也是准备后续再做的,以现在的结构而言,支持起来很简单。

现在我正在考虑把单位时间内的多个get合并成一个gets操作,这样对系统性能提升应该有更大的帮助。



序列化和反序列化完成后,有时间我来做个完成的性能测试。
15 楼 uniseraph 2008-10-22  
liuye 写道

get/set只能对字符串/字节操作,Object怎么办?另外,是不是没有考虑连接多个memcached服务器呀?


有数据了,再进行序列化和反序列化是很简单的。后续会包装一些接口。

连接多个服务器也是准备后续再做的,以现在的结构而言,支持起来很简单。

现在我正在考虑把单位时间内的多个get合并成一个gets操作,这样对系统性能提升应该有更大的帮助。
14 楼 davidgrubby 2008-10-22  
干得不错,一起研究一下
13 楼 liuye 2008-10-22  
get/set只能对字符串/字节操作,Object怎么办?另外,是不是没有考虑连接多个memcached服务器呀?
12 楼 fredguo 2008-10-22  
学习ing
11 楼 uniseraph 2008-10-21  
liyao20050101 写道

补充下lib嘛。


编译的时候,会自动下载lib。

相关推荐

    memcached1

    Memcached是高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度。Memcached由Danga Interactive开发,用于提升LiveJournal.com访问速度的。LJ每秒动态页面访问量几千次,用户700万...

    java开源包1

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    Xmemcached用户指南

    Memcached 是一个高性能的分布式内存对象的key-value缓存系统,用于动态Web应用以减轻数据库负载,现在也有很多人将它作为内存式数据库在使用,memcached通过它的自定义协议与客户端交互,而XMemcached就是它的一个...

    JAVA上百实例源码以及开源项目

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    java开源包4

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包11

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    JAVA上百实例源码以及开源项目源代码

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    java开源包6

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包101

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包9

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包5

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包8

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包10

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包3

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包2

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    java开源包7

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    Java资源包01

    xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...

    Xmemcached测试实例

    测试类包括Xmemcached客户端与memcached client for java两者,可运行比较性能。 XMemcached简介: XMemcached是基于 java nio的Memcached客户端,java nio相比于传统阻塞 io 模型来说,有 效率高(特别在高并发下...

Global site tag (gtag.js) - Google Analytics