gpt4 book ai didi

java - Spring 范围 =`prototype` : how to change all bean instances?

转载 作者:行者123 更新时间:2023-12-01 13:47:04 26 4
gpt4 key购买 nike

我有一个简单的类,它对正则表达式模式列表执行一些检查。我的模式是通过恒定的值列表以某种方式设置的。目前这不是一个问题,所以我省略了该设置代码。

class Checker {
private final Pattern [] patterns = new Pattern[10];

public boolean check(final String param){
for(Pattern p : patterns){
if(p.matcher(param).matches())
return true;
}
return false;
}
}

事情很简单。现在我正在从 500 个并发线程访问该类。类是使用默认的 Spring 作用域 singleton 创建的。

同步访问模式:

class Checker {
private final Pattern [] patterns = new Pattern[10];

public boolean check(final String param){
synchronized(patterns){
for(Pattern p : patterns){
if(p.matcher(param).matches())
return true;
}
return false;
}
}
}

好吧,由于所有线程都访问我的类的单个实例 - 它们被锁定在同步块(synchronized block)中。由于我的类相当轻量级,我想为每个线程创建单独的实例(例如,将范围从 singleton 更改为 prototype)。删除同步块(synchronized block)并添加由 ThreadLocal 支持的 getInstance 工厂方法。像这样:

class Checker {
private final Pattern [] patterns = new Pattern[10];

public boolean check(final String param){
for(Pattern p : patterns){
if(p.matcher(param).matches())
return true;
}
return false;
}

private static final ThreadLocal<Checker> checkerLocal =
new ThreadLocal<Checker>() {
@Override
protected Checker initialValue() {
System.out.println("Creating Checker instance")
return new Checker();
}
};

public static Checker getInstance(){
return checkerLocal.get();
}
}

就像魅力一样。

但是,想象一下我必须在应用程序内部动态以某种方式修改模式(例如,在其中添加或删除模式)。我应该对 Checker 类的所有现有实例执行此操作。我正在考虑使用 ApplicationContext#getBeansOfType(Checker.class) 方法来获取所有 bean 实例。但是还有其他更有弹性的方法吗?

最佳答案

这是我的建议。 Checker类根本不需要任何同步,因为它只提取不可修改的 List<Pattern>在持有者类之外,唯一需要的同步是防止持有者上的更新冲突。

public class PatternService {
AtomicReference<List<Pattern>> patterns = new AtomicReference<>(Collections.emptyList());

public List<Pattern> getPatterns() {
return patterns.get();
}

public synchronized void addPattern(Pattern p) {
List<Pattern> newPatterns = new LinkedList<>(patterns.get());
newPatterns.add(p);
patterns.set(Collections.unmodifiableList(newPatterns)); // or ImmutableList
}

// other mutators
}


public class Checker {
@Autowired PatternService patternService;

public boolean check(String param) {
for(Pattern p: patternService.getPatterns())
if(p.matcher(param).matches())
return true;

return false;
}
}

关于java - Spring 范围 =`prototype` : how to change all bean instances?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20288494/

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