Webアプリケーションでは、バックグラウンドサービスがあります。このサービスは、Engineクラスと複数スレッドを使用するように構成されたExecutorService
を含むGeneratorクラスを使用し、GeneratorTasksを受け入れます。Spring BeanをExecutorServiceのThreadLocalインスタンスのように動作させる
@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変数を挿入する別の方法があるかどうか疑問に思っていました。私はrequest
スコープにBeanのスコープを見てきましたが、私はどのように私はそれが私のデザインを与えて行く必要がありますか分からない。
私のデザインを改善する方法についてのガイダンスは高く評価されます。
:スレッドスコープのBeanを宣言するために、その後
そして:ために
は、カスタムスコープを登録する必要があり、それを使用するにはBeanとして宣言しました。デフォルトでは、Spring Beanはシングルトンなので、 'Engine'が既にシングルトンであるという良いチャンスがあります... –
申し訳ありませんが私は不明確かもしれません。私の問題は、処理ロジックのために複数の同時スレッドがアクセスできないため、エンジンをシングルトンにすることができないことです。完全な「仕事」が完了したら、エンジンを再利用することは安全です。そのため、私はそれを使用するスレッドごとにインスタンスを作成することを考えていました。 –
私はあなたの現在のコードエンジンでは、コードが実際に何をしているのか望んでいなくても、すでにシングルトンであると言っていました。 –