W mojej aplikacji internetowej mam usługę w tle. Ta usługa używa klasy Generator zawierającej klasę Engine i ExecutorService
skonfigurowaną do używania wielu wątków i akceptującą GeneratorTasks.Tworzenie fasoli szparagowej zachowuje się jak instancje ThreadLocal dla ExecutorService
@Component
public class Generator {
@Autowired
private Engine heavyEngine;
private ExecutorService exec = Executors.newFixedThreadPool(3);
//I actually pass the singleton instance Generator class into the task.
public void submitTask(TaskModel model, TaskCallback callback) {
this.exec.submit(new GeneratorTask(model, this, callback));
}
}
@Component
public class Engine {
public Engine() {
//time-consuming initialization code here
}
}
public class GeneratorTask implements Callable<String> {
public GeneratorTask(TaskModel m, Generator g, ReceiptCallback c) {
this.m = m;
this.generator = g;
this.c = c;
}
public String call() throws Exception {
//This actually calls the Engine class of the generator.
//Maybe I should have passed the Engine itself?
this.generator.runEngine(c);
}
}
Inicjowanie klasy Engine zajmuje dużo czasu, więc najlepiej zainicjować ją tylko raz na wątku. Nie mogę zrobić tego pojedynczego wystąpienia, ponieważ instancja nie może być współużytkowana w wielu wątkach (polega na przetwarzaniu sekwencyjnym). Ponowne użycie instancji po zakończeniu zadania przetwarzania jest całkiem w porządku.
Zastanawiam się nad zmienną private Engine heavyEngine
zmienną ThreadLocal. Jednak jestem również nowy w Spring, więc zastanawiałem się, czy istnieje inny sposób na wstawienie zmiennych ThreadLocal przy użyciu adnotacji wiosennych. Przyjrzałem się zakresowi fasoli do zakresu request
, ale nie jestem pewien, jak powinienem to zrobić, biorąc pod uwagę mój projekt.
Wszelkie wskazówki dotyczące ulepszenia mojego projektu będą mile widziane.
Ponieważ 'Engine' jest autowired Zakładam, że masz oświadczył to jako fasola. Domyślnie fasolka Spring jest singleton, więc istnieje duża szansa, że 'Engine' jest już singletonem ... –
Przepraszam, mogłem być niejasny. Mój problem polega na tym, że nie mogę uczynić silnika pojedynczym, ponieważ ze względu na jego logikę przetwarzania nie można uzyskać dostępu do wielu współbieżnych wątków. Bezpiecznie jest ponownie użyć Silnika po zakończeniu "pracy", dlatego zastanawiałem się nad stworzeniem instancji na wątek, który jej używa. –
Rozumiem, mówiłem, że z twoim aktualnym kodem Engine jest już singletonem, nawet jeśli nie jest to, co chcesz, to jest to, co faktycznie robi twój kod. –