У меня есть простой класс, который выполняет некоторые проверки снова список шаблонов Regex. Мои шаблоны задаются каким-то образом с постоянным списком значений. На данный момент это не вопрос, поэтому я опускаю этот код настройки.Spring scope = `prototype`: как изменить все экземпляры bean?
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 одновременных потоков. Класс создается с весовой шкалой по умолчанию singleton
.
Обеспечение доступа к patterns
синхронным:
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;
}
}
}
Ну, так как все потоки получают доступ к одному экземпляру моего класса - они блокируются внутри синхронизированного блока. Поскольку мой класс довольно легкий, я хотел бы создать отдельный экземпляр для каждого потока (например, сменить область от singleton
до prototype
). Извлечение блока синхронизации и добавление getInstance
заводского метода при поддержке ThreadLocal
. Например:
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. Но есть ли еще какой-нибудь другой способ сделать это?
Мне сложно понять, что вы пытаетесь выполнить. Является '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Если это так, не будет использовать прототип bean победить цель? Объекты 'Pattern' являются потокобезопасными, поэтому кажется, что имеет смысл просто использовать поточно-безопасную коллекцию и удалять синхронизацию на' check'. – chrylis
Да. Мой вопрос заключался в том, как динамически изменять «шаблоны» во всех экземплярах «прототипа»;) – Archer
По-прежнему не понимаю, почему вы в первую очередь сделали 'check'' synchronized'. – chrylis