免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 995 | 回复: 0
打印 上一主题 下一主题

ThreadLocal与对象重用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-07-28 10:16 |只看该作者 |倒序浏览
大家知道,java的内存管理机制是依靠垃圾收集器来完成的,其原理主要是对每一个线程作引用的有向图遍历,这种方式比起perl等完全依靠引用计数的语言来讲更为复杂,运算量也更多。由于这个机制,也造成了java编成风格上的内存浪费(不是泄漏)非常普遍。比如大量的局部Object变量的创建,什么时候想用了,就new 一个。这当然无可厚非,但是,高效率,不间断,要求减少垃圾收集的次数对于一些特定的实时系统来讲是非常有意义的。对象重用便是一个很好的解决方法。
大家知道,java的内存管理机制是依靠垃圾收集器来完成的,其原理主要是对每一个线程作引用的有向图遍历,这种方式比起perl等完全依靠引用计数的语言来讲更为复杂,运算量也更多。由于这个机制,也造成了java编成风格上的内存浪费(不是泄漏)非常普遍。比如大量的局部Object变量的创建,什么时候想用了,就new 一个。这当然无可厚非,但是,高效率,不间断,要求减少垃圾收集的次数对于一些特定的实时系统来讲是非常有意义的。对象重用便是一个很好的解决方法。
    这里我们不介绍对象池,如Jakarta Object Pool等的相对复杂的对象重用机制。而是介绍一种非常简单的重用方法。这个方法的思路只有一点,就是每一个线程对于每一个需要重用的对象的类拥一个实例。这样的好处是:
    1,对象少,每一种类的对象数与线程数相同。
    2,不用同步,没有效率上的问题。
    实现的手段非常简单,就是利用ThreadLocal类。ThreadLocal类保证了每一个线程拥有不同的实例,而同一个线程一定是同一个实例。
    这是我写的一个简单的重用对象工厂类,对于StringBuffer,List等常用的临时变量类型,都可以直接用getObject方法得到本线程中的实例,然后调用clear()或其他方法初始化一下就可以用了。但是必须注意,这个Object一定是临时的,其生存期不能超出其定义所在的方法,千万不能放到全局的数据结构或容器中。
    import java.util.*;
/**
*
* @author  lie.xiao
*/
public class ThreadLocalObjFactory {
   
    private static Hashtable resourceTable = new Hashtable();
    public static Object getObject(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        return getObject(className, null);
    }
   
    public static Object getObject(String className, ClassLoader loader) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        if (resourceTable.containsKey(className)) {
            ThreadLocal threadLocal = (ThreadLocal)resourceTable.get(className);
            Object o = threadLocal.get();
            if (o == null) {
                if (loader == null) {
                    o = Class.forName(className).newInstance();
                } else {
                    loader.loadClass(className).newInstance();
                }
                threadLocal.set(o);
            }
            return o;
        } else {
            ThreadLocal threadLocal = new ThreadLocal();
            Object o = null;
            if (loader == null) {
                o = Class.forName(className).newInstance();
            } else {
                loader.loadClass(className).newInstance();
            }
            threadLocal.set(o);
            resourceTable.put(className, threadLocal);
            return o;
        }
    }


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/5142/showart_38032.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP