oldratlee/translations

clean extra TTL value in destination thread

tianjialin opened this issue · 3 comments

您好,请教一个问题:

TransmittableThreadLocal类中的 backupAndSet() 方法中,如下代码:

for (Iterator<? extends Map.Entry<TransmittableThreadLocal<?>, ?>> iterator = holder.get().entrySet().iterator();
             iterator.hasNext(); ) {
    Map.Entry<TransmittableThreadLocal<?>, ?> next = iterator.next();
    TransmittableThreadLocal<?> threadLocal = next.getKey();

    // 此处将线程池所在线程threadlocal备份
    backup.put(threadLocal, threadLocal.get());

    // 没太理解此处,为何将copied中不存在,holder中存在的 threadlocal remove?
    if (!copied.containsKey(threadLocal)) {
        iterator.remove();
        threadLocal.superRemove();
    }
}

一旦调用iterator.remove()本来不属于当前线程的threadlocal也会被remove,这样假如此时另外一个线程池中的线程调用了copy()方法,就会丢失部分数据?

不知我哪里理解错误,望批评指正。
期待回复

这样假如此时 另外一个线程池中的线程 调用了copy()方法

holder.get()ThreadLocal的(holder本身是ThreadLocal),只属于当前线程。
# ThreadLocal#get() 只能 拿到 当前线程 的数据。

即这个数据不会被另一个线程访问使用的,没有并发问题。

更具体 可以再看看一下ThreadLocal的使用与限制。


// 没太理解此处,为何将copied中不存在,holder中存在的 threadlocal remove?

// clear the TTL value only in copied
// avoid extra TTL value in copied, when run task.
if (!copied.containsKey(threadLocal)) {
    iterator.remove();
    threadLocal.superRemove();
}

上面的代码注释 说明了。

如果不这么做这个删除,那么 TTL这些值 就比 copied 里多出来了,
不没有正确 恢复/回放值。

比如 原来的copy过来的值是 a=1,b=2,回放运行的线程原来就有值z=100
不做这个删除,回放运行时,就有值a=1,b=2,z=100,不预期了。

可以自己写段代码运行Debug一下就好了,或者 自己理解一下TTL的执行过程,这个就很容易理解了。


PS

这个Issue也提交错了 仓库,@tianjialin 请 提交到 ❤️
https://github.com/alibaba/transmittable-thread-local/issues

仔细有想了想 ThreadLocal 的运行原理,理解了,非常感谢百忙之中回复。

另:
我是单击 TransmittableThreadLocal 仓库下README里 “建议和提问,提交Issue” 进来的,我还以为提问都是在这提问。操作有误,实在抱歉

麻烦 提到ttl中,方便大家也看到了解,谢谢

我是单击 TransmittableThreadLocal 仓库下README里 “建议和提问,提交Issue” 进来的,我还以为提问都是在这提问。

README 有误,给个pr fix一下? 💕