Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clean extra TTL value in destination thread #90

Closed
tianjialin opened this issue Apr 17, 2018 · 2 comments
Closed

clean extra TTL value in destination thread #90

tianjialin opened this issue Apr 17, 2018 · 2 comments
Assignees
Labels
❓question Further information is requested

Comments

@tianjialin
Copy link
Contributor

tianjialin commented Apr 17, 2018

您好,请教一个问题:

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()方法,就会丢失部分数据?

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


此Issue为提交错误地址后粘贴过来的
oldratlee/translations#51 (comment)

@tianjialin
Copy link
Contributor Author

问题的原因是没注意到holder的几点需要注意的地方:
1、holder 是 InheritableThreadLocal 变量;
2、holder 是 static 变量;
3、value 是 WeakHashMap;
4、深刻理解 ThreadLocal 工作原理;

@oldratlee
Copy link
Member

oldratlee commented Apr 17, 2018

这样假如此时 另外一个线程池中的线程 调用了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的执行过程,这个就很容易理解了。


此Issue为提交错误地址后粘贴过来的
oldratlee/translations#51 (comment)

PS:

@tianjialin 的讨论文章:
TransmittableThreadLocal详解 https://www.jianshu.com/p/e0774f965aa3
# 汇总在了 #123 小伙伴同学们写的 TTL使用场景 与 设计实现解析的文章(写得都很好! )❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
❓question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants