关于Java ThreadLocal的疑问

ThreadLocal作为一个可以将数据进行线程隔离的解决方法,其本质还是将数据存放在各个线程对象中(数据存放在Thread的ThreadLocalMap threadLocals中);

那么为什么JDK不在设计的时候就使Thread对象具有保存线程上下文的能力呢?
比如可以这样:
[code="java"]public class Thread
{
...
private Map contexts = new WeakHashMap();
public void setContext(Object key, Object value)
{
contexts.put(key, value);
}
public void getContext(Object key)
{
contexts.get(key);
}
}[/code]
使用的时候Thread.getCurrentThread.getContext(key);简单方便

JDK实现者是出于什么考虑才这样设计的?

0

4个回答

楼主你真的很搞笑,你这样就违背了数据的封装原则。Thread作为类,为什么要提别人保存属性啊 就好比一个people类,存放很多别人的名字一样 。首先threadlocal是一个类,但是他的使用原则,是有多个线程共同工作在一个环境下,如果乜有threadlocal类,那么在实际的编码中,我们很喜欢调用一个帮助类,来辅助解决这个问题的。如ThreadHelper之类的。

0
renminzdb2
renminzdb2 附带一句,threadLoacl 本身就是一个障眼法……没必要计较这么多 也不知道是哪个想的这个方法这么设计的,然后就都这么用了……
大约 5 年之前 回复
renminzdb2
renminzdb2 ThreadLocal实际上也是把对象保存在Thread对象中,这句话很难理解,你是说ThreadLocal类作为Thread属性么? 你看看楼下的代码,你不好奇为啥ThreadLocal 定义成全局的啊,实际上这个类是独立的个体,之所以能那么调用,是因为保存变量的时候,跟线程的id绑定了,外部随便一个set get方法看上去很简单,其实都是对调用线程有个隔离的一对一服务。这样就避免了线程对资源的竞争。为什么不是作为属性自己增加到线程类中,我想可能一,额外增加消耗 二,不够灵活。你自己写的那个put set 还是需要取别名的。哪有threadLocal直接呢,而且耦合性也降低了不少
大约 5 年之前 回复
Sweeping_Monk
Sweeping_Monk 我不太同意你的说法,ThreadLocal实际上也是把对象保存在Thread对象中的,只是访问被保存对象的方法从Thread,移到ThreadLocal中了,感觉绕了一圈
大约 5 年之前 回复

这个没有必要在jdk里面加,使用了线程不一定就得使用一个上下文变量,不用的时候就多余了,所以还是开发人员自己定义。

0
Sweeping_Monk
Sweeping_Monk 那我上面的代码可以在第一次setContext的时候再去创建map,ThreadLocal就是这样实现的; 所以你这么解释不太通。。。
大约 5 年之前 回复

[code="java"]、
package threadLoacl;

import java.sql.Connection;
import java.sql.SQLException;

/**

  • 数据库连接管理类
  • @author 爽
    *
    */
    public class ConnectionManager {

    /** 线程内共享Connection,ThreadLocal通常是全局的,支持泛型 */
    private static ThreadLocal threadLocal = new ThreadLocal();
    // private static ThreadLocal threadLocal1 = new ThreadLocal();

    public static Connection getCurrConnection() {
    // 获取当前线程内共享的Connection
    Connection conn = threadLocal.get();
    try {
    // 判断连接是否可用
    if(conn == null || conn.isClosed()) {
    // 创建新的Connection赋值给conn(略)
    // conn =new Connection();
    // 保存Connection
    threadLocal.set(conn);
    }
    } catch (SQLException e) {
    // 异常处理
    }
    return conn;
    }

    /**

    • 关闭当前数据库连接 */ public static void close() { // 获取当前线程内共享的Connection Connection conn = threadLocal.get(); try { // 判断是否已经关闭 if(conn != null && !conn.isClosed()) { // 关闭资源 conn.close(); // 移除Connection threadLocal.remove(); conn = null; } } catch (SQLException e) { // 异常处理 } } } [/code] 比如上面的代码。 我想到一点,threadLocal 这个是类变量,不用到处写Thread.getCurrentThread.getContext(key)这样的代码了,而且你不用在set、get时自己关注key是什么。
0
Sweeping_Monk
Sweeping_Monk @author名字很逗。。。 你这么说有道理
大约 5 年之前 回复

1、ThreadLocal的实现对其他线程是不可见的,你的实现方法对其他线程可见,没有很好的隔离。
2、ThreadLocal相对HashMap还做了一些性能优化。在Java系统里ThreadLocal使用非常普遍,最常用的String类的编解码都要使用它。性能是很重要的。

0
taolei
taolei 我说的是对其他线程可见,不是对其他对象可见
大约 5 年之前 回复
Sweeping_Monk
Sweeping_Monk 你的第一点我认为不对,第二点有道理 第一点:这个map是放在Thread类里面的,它不是静态的,对其他对象不可见的。
大约 5 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!