gpt4 book ai didi

Java 实例成员和并发

转载 作者:行者123 更新时间:2023-11-30 11:09:59 25 4
gpt4 key购买 nike

鉴于我对 java 中并发性的理解,似乎必须对实例成员的共享访问进行编码,以便仅当线程访问给定对象(例如 servlet)的同一实例时才能处理多线程访问。参见此处: Why instance variable in Servlet is not thread-safe

由于并非所有应用程序都是基于 servlet 的,您如何确定哪些对象需要适应多线程访问?例如,在一个大型的、非基于 servlet 的企业应用程序中,鉴于类的绝对数量,您如何从设计的角度确定哪些对象在运行时将只有一个实例在多个线程之间共享?我能想到的唯一情况就是单例。

在 Java 的 EL API 中,javax.el.BeanELResolver 有一个私有(private)内部类,它使用同步来序列化对其成员之一的访问。除非我遗漏了什么,否则 BeanELResolver 看起来不像一个单例,因此每个线程都应该有自己的 BeanELResolver 实例。同步其中一个成员背后的设计考虑可能是什么?

最佳答案

在很多情况下,一个类的状态可以在多个线程之间共享,而不仅仅是单例。例如,您可以让一个类或方法创建对象(某种工厂)并在所有创建的对象中注入(inject)相同的依赖项。注入(inject)的依赖项将在调用工厂方法的所有线程之间共享。依赖项可以是任何东西:计数器、数据库访问类等。

例如:

class ThreadSafeCounter{
/* constructor omitted */
private final String name;
private final AtomicInteger i = new AtomicInteger();
int increment() { return i.incrementAndGet(); }
}

class SheepTracker {
public SheepTracker(ThreadSafeCounter c) { sheepCounter = c;}
private final ThreadSafeCounter sheepCounter;
public int addSheep() { return c.increment(); }
}

class SheepTrackerFactory {
private final ThreadSafeCounter c;
public SheepTracker newSheepAdder() {
return new SheepTracker(c);
}
}

在上面,SheepTrackerFactory 可以被许多线程使用,它们都需要做同样的事情,即跟踪羊。所有线程中的绵羊数量都保存在全局状态变量 ThreadSafeCounter 中(在此示例中它可能只是一个 AtomicInteger,但请耐心等待,您可以想象一下这个类如何包含额外的状态/操作)。现在每个 SheepTracker 都可以是一个轻量级类,可以执行其他不需要同步的操作,但是当它们需要增加羊的数量时,它们将以线程安全的方式进行。

关于Java 实例成员和并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27924720/

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