同人展馆

ThreadLocal为什么要设计成private static

https://www.zhihu.com/question/35250439

结论:

1 static 防止无意义多实例

2 当static时,ThreadLocal ref生命延长-ThreadMap的key在线程生命期内始终有值-ThreadMap的value在线程生命期内不释放——故线程池下,static修饰TrheadLocal引用,必须(1)remove 或(2)手动 ThreadLocal ref = null

两个例子:

A 《多线程实战》上ThreadLocal的一个实例

作者测试的顺序:

1 创建10000个runnable对象放入max 10的线程池,创建10个Thread,即10个~Map;

2 新建ThreadLocal(1)对象,调用get/set,产生10个SimpleDateFormat对象;

3 static ThreadLocal red = null ,此时ThreadLocal对象仅有一个弱引用,在Thread.~Map中;

4 第一次gc,回收了ThreadLocal对象,同时致使 Thread.~Map中存在10个key为null的value;

5 再创建10000个runnable对象,放入线程池原先的10个线程;

6 新建ThreadLocal(2)对象,调用set,触发新变量加入Thread.~Map,进而触发中key为null的value对象被置为可回收对象,原先的value对象与Thread的强引用断开

7 第二次gc,正式回收被与Thread断开强引用的10个SimpleDateFormat对象

B 模仿spring事务框架时的一个数据库连接例子

Java事务处理全解析(四)—— 成功的案例(自己实现一个线程安全的TransactionManager)

http://blog.csdn.net/huilangeliuxin/article/details/43446733

这篇文章中有个实例:

定义一个线程安全的SingleThreadConnectionHolder类如下:

[java] view plain copy

public class SingleThreadConnectionHolder

{

private static ThreadLocal localConnectionHolder = new ThreadLocal();

public static Connection getConnection(DataSource dataSource) throws SQLException

{

return getConnectionHolder().getConnection(dataSource);

}

public static void removeConnection(DataSource dataSource)

{

getConnectionHolder().removeConnection(dataSource);

}

private static ConnectionHolder getConnectionHolder()

{

ConnectionHolder connectionHolder = localConnectionHolder.get();

if (connectionHolder == null)

{

connectionHolder = new ConnectionHolder();

localConnectionHolder.set(connectionHolder);

}

return connectionHolder;

}

}

可以看到,每次事务提交后,都调用remove,防止连接泄露

Copyright © 2088 承德书写游戏活动中心 - 剧情创作专属天地 All Rights Reserved.
友情链接