クラスがあるとします:
public class MyTask implements Runnable {
@Inject
private Fizz fizz;
// Getters and setters for 'fizz'.
@Override
public void run() {
if(fizz.alleviatesBuzz())
doA();
else
doB();
}
private void doA() { ... }
private void doB() { ... }
}
そして、私は別のクラスを持っています:
public class MyTaskDispatcher {
@Inject
private ThreadFactory threadFactory;
private Executor executor;
// Getter and setter for 'threadFactory'.
public void dispatch(MyTask task) {
if(executor == null)
executor = Executors.newCachedThreadPool(threadFactory);
executor.submit(task);
}
}
そのため、 Guice は を注入MyTask
し、渡されたインスタンスの作成と実行に使用されるFizz
も注入MyTaskDispatcher
します。また、キャッシュされたプールであるため、新しいスレッドが必要であるが使用できない場合にのみ新しいスレッドを作成します。ThreadFactory
MyTask
Fizz
シングルトンまたは非シングルトンとして注入する場合、マルチスレッド環境で Guice がどのように「動作」するのか疑問に思っています。
たとえば、非シングルトンから始めましょう。
public class MyAppModule extends AbstractModule {
@Override
public void configure() {
bind(Fizz.class).to(FizzImpl.class);
// I don't think the functionality of MyThreadFactory
// really matters for the sake of this question.
bind(ThreadFactory.class).to(MyThreadFactory.class);
}
@Provides
FizzImpl providesFizz() {
return new FizzImpl(true, Buzz.ALWAYS, 35);
}
// I *believe* we always want the ThreadFactory to be singleton,
// because all of the threads spawn from it and its executor.
@Provides @Singleton
ThreadFactory providesThreadFactory() {
return new MyThreadFactory(12);
}
}
ここで、アプリがしばらく実行されていて、3 つの個別MyTask
の が送信されたため、3 つの実行中のスレッドが存在するとします。es をシングルトンとして注入するように Guice に依頼しなかったのでFizz
、各スレッドには注入された の独自のコピーがあり、3 つの s が衝突してスレッドの問題が発生するのを防ぐために -type コードをFizzImpl
追加する必要はないと仮定します。synchronize
FizzImpl
しかし、Guice をFizzImpl
シングルトンとして注入するとどうなるでしょうか?!? 今、でMyAppModule
:
@Provides @Singleton
FizzImpl providesFizz() {
return new FizzImpl(true, Buzz.ALWAYS, 35);
}
Guice が の 1 つのグローバルなシングルトン インスタンスのみを提供する場合、生成された 3 つのスレッドのそれぞれの内部で、その「コピー」FizzImpl
の下流への影響は何ですか (それが正しい言葉である場合)。FizzImpl
注意すべき落とし穴とは?これらの落とし穴に対抗する方法は何ですか? 前もって感謝します。