gpt4 book ai didi

java - ThreadLocal 和非线程安全 API

转载 作者:行者123 更新时间:2023-12-03 19:42:22 27 4
gpt4 key购买 nike

所以我有一个我目前正在使用的非线程安全 API(一些供应商软件),我们目前使用它的方式是每个线程一个对象。即每个线程都有:

Foo instance = new Foo();

但是,这似乎不适用于这个特定的库。它的一些非线程安全位似乎仍然令人头疼,所以我假设这个库中有一些静态值。在我们知道它有问题的几个点上,我们目前正在使用 ReentrantLock 在需要时锁定类。即

public class Bar {
protected static final ReentrantLock lock = new ReentrantLock();

public void process() {
Foo instance = new Foo();
boolean locked = false;
try{
if(SomeCondition) {
locked = true;
Bar.lock.lock();
}

*//rest of the processing goes here

} finally {
if(locked){
Bar.lock.unlock();
}
}
}
}

我的问题是:在这种情况下,所讨论的类不是线程安全的,即使在创建所述类的新实例时,使用锁定更好,还是我应该改用 ThreadLocals? ThreadLocals 会缓解我的实际问题吗?类的 ThreadLocal 版本实际上是否强制类的静态区域本质上是非静态的?

最佳答案

ThreadLocal 所做的只是创建一个查找,每个线程都可以在其中找到自己的对象实例,因此没有线程必须共享。从概念上讲,您可以将其视为以线程 ID 为键的映射。

让每个线程使用自己的对象在某些情况下是一个很好的策略,在 JCIP 书中称为“线程限制”。一个常见的例子是 SimpleDateFormat 对象没有设计成线程安全的,使用它们的并发线程会产生不好的结果。使用 ThreadLocal 可以让每个线程使用自己的 DateFormat,see this question for an example .

但是如果您的问题是对象引用了静态字段,那么这些静态字段存在于类中,而不是实例中,因此使用 ThreadLocal 不会减少共享。

如果您的每个线程都以某种方式使用自己的类加载器,那么每个线程都会有自己的类,并且不会共享其上的静态字段。否则,您对类(class)的锁定似乎是合理的(尽管考虑到您的所有线程都会争用同一个锁,但可能不会很快)。最好的方法是与供应商合作,让他们修复损坏的代码。

关于java - ThreadLocal 和非线程安全 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37441030/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com