私のWebアプリケーションには、バックグラウンドサービスがあります。このサービスは、Engineクラスを含み、ExecutorService
複数のスレッドを使用するように構成され、GeneratorTasksを受け入れるGeneratorクラスを使用します。
@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);
}
}
Engineクラスは初期化に時間がかかるので、理想的にはスレッドごとに1回だけ初期化したいと思います。インスタンスは複数のスレッド間で共有できないため、シングルトンインスタンスにすることはできません(順次処理に依存しています)。ただし、処理タスクが完了した後、インスタンスを再利用することはまったく問題ありません。
private Engine heavyEngine
変数をThreadLocal変数にすることを考えていました。ただし、私はSpringも初めてなので、Springアノテーションを使用してThreadLocal変数を挿入する別の方法があるのではないかと考えていました。Beanのスコープを指定することを検討しましたがrequest
、設計上、どのように処理すればよいかわかりません。
私のデザインを改善する方法についてのガイダンスをいただければ幸いです。