Tuesday 24 June 2008

说,谁能为emacs创建一个code_swarm,就像有人为eclipse和python创建的那样:

http://vis.cs.ucdavis.edu/~ogawa/codeswarm/


于是RMS跳出来了,说,那视频的格式呢?我们一定要坚持使用自由的格式,
比如OGG格式。

谁还坚持这个原则呢?还有谁呢?

Tuesday 17 June 2008

Thread, ThreadPool and ThreadLocal

孙悟空有72个线程(Thread)。他同时可以做72件事情。在没事的时候,这72个线程监听一个任务队列(Task Queue),等待任务(Task),不怎么消耗资源;当一个任务来的时候,这72个线程中的一个会得到这个任务,并去执行。因此孙悟空的这72个线程可以称作一个线程池(ThreadPool)。



线程池的一个线程有两种状态:等待任务和执行任务。等待任务并不意味着该线程是死的,就像人睡觉不等于死一样。有些任务在执行过程中,会往线程上放一些数据,这些数据只期望在线程内能访问到。这些数据叫线程本地数据(ThreadLocal)。



一个任务执行完了,执行该任务的线程会等待新的任务来执行。任务结束并不等于线程结束。那些线程本地数据也还在,不会被清理。因此当一个任务运行多次,可能发现一些现成本地数据是脏的(Dirty)。



那怎么办呢?



一个策略是设计线程池的时候,就考虑线程本地数据的清理。对一般已有的线程池实现,靠谱的也会考虑这个问题。

Sunday 15 June 2008

Java私有方法的测试

Java世界里最臭名昭著私有方法估计就是类java.io.ObjectInputStream里的`latestUserDefinedLoader'。这个方法的行为多少有点让人捉摸不透。这个类还是一个私有的、本地的方法(private, native)。

下面两个方法使`latestUserDefinedLoader'的测试变得容易:
,----[ Class LatestUserDefinedLoaderUtil ]
| public static ClassLoader latestUserDefinedLoader() throws Exception {
| ClassLoader latestUserDefinedLoader = (ClassLoader) invokeStaticMethod(
| ObjectInputStream.class, "latestUserDefinedLoader");
| return latestUserDefinedLoader;
| }
|
| public static Object invokeStaticMethod(Class klass, String name)
| throws Exception {
| Method method = klass.getDeclaredMethod(name, new Class[0]);
| method.setAccessible(true);
| return method.invoke(null, null);
| }
`----
为了测试latestUserDefinedLoader的行为,再增加两个方法:
,----[ Class LatestUserDefinedLoaderUtil Continue ]
| public static String getClassName() {
| return LatestUserDefinedLoaderUtil.class.getName();
| }
|
| public static URL getResource() throws Exception {
| String resName = getClassName().replace('.', '/') + ".class";
| String resource = Thread.currentThread().getContextClassLoader().getResource(resName).toString();
| return new URL(resource.substring(0, resource.indexOf(resName)));
| }
`----
下面是一个不那么复杂的测试用例:
,----
| public void testLatestUserDefinedLoader() throws Exception {
| URL[] urls = new URL[1];
| urls[0] = LatestUserDefinedLoaderUtil.getResource();
| System.out.println(urls[0]);
| ClassLoader classLoader = new URLClassLoader(urls, null);
| Class klass = LatestUserDefinedLoaderUtil.class;
| Class theKlass = classLoader.loadClass(LatestUserDefinedLoaderUtil.getClassName());
| assertNotNull(theKlass);
| ClassLoader latestUserDefinedLoader = (ClassLoader)
| LatestUserDefinedLoaderUtil.invokeStaticMethod(theKlass, "latestUserDefinedLoader");
| assertEquals(classLoader, latestUserDefinedLoader);
| }
`----