、あなたの観察者の基本的な実装は次のようになります。
class ObserverA implements Runnable {
private final BlockingQueue<Food> queue = new ArrayBlockingQueue<>();
public void eatFood(Food f) {
queue.add(f);
}
public void run() {
try {
while (true) {
Food f = queue.take(); //blocks until some food is on the queue
//do what you have to do with that food
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
//and exit
}
}
}
のでeatFood
を呼び出すコードは、あなたのメインスレッドをブロックする方法から、すぐに戻っていないでしょう。
オブザーバーにスレッドを割り当てる必要があります。具体的には、直接new Thread(observerA).start();
またはExecutorServiceを使用します。これはおそらくより簡単で好ましい方法です。
代わりに、あなたは「観察」オブジェクトレベルでスレッドを作成することができます。
private static final ExecutorService fireObservers = Executors.newFixedThreadPool(10);
public void eat(Food food) {
for (AbstractObserver o : observers) {
//(i) if an observer gets stuck, the others can still make progress
//(ii) if an observer throws an exception, a new thread will be created
Future<?> f = fireObservers.submit(() -> o.dataChanged(food));
fireObservers.submit(new Callable<Void>() {
@Override public Void call() throws Exception {
try {
f.get(1, TimeUnit.SECONDS);
} catch (TimeoutException e) {
logger.warn("Slow observer {} has not processed food {} in one second", o, food);
} catch (ExecutionException e) {
logger.error("Observer " + o + " has thrown exception on food " + food, e.getCause());
}
return null;
}
});
}
}
(私は主にhereから貼り付けコピーされた - あなたはおそらくあなたのニーズに適合させる必要があります)。への出口で
// declare the work queue
private final Executor workQueue = Executors.newCachedThreadPool();
// when you want to eat, schedule a bunch of 'eating' jobs
public void eat(final Food item){
for (final AbstractObserver o: list) {
workQueue.execute(new Runnable() {
@Override
public void run() {
o.eatFood(item); // runs in background thread
}
});
}
}
を:あなたはまた、待ち行列に作業をスローするようにエグゼキュータのフレームワークを使用することができ、とき食べる/飲む終了通知取得を気にしないことをここにいくつかの単純化の仮定を作る
オブザーバーがここでどのように役割を果たすのか分かりません。彼らが観察する科目は何ですか?また、どのように食べ物に関係しますか?食べ物と飲み物の方法は何ですか? – Philipp
いいえ、私のためではありません。私の見解では、いつ飲食(MAINスレッドメソッド)が呼び出されるのか分かりません。彼らは5分以上離れて呼び出すことができます。 MAINスレッドの食べ物や飲み物のメソッドが呼び出されたときに、個々のAbstractObserverサブクラスインスタンスが同時にdrinkCoffeeまたはeatFoodを実行できるようにしたいだけです。 – sneeze1
並行処理に制限はありますか?例えば、前のo.eatFood()が終了する前に、同じオブジェクトの次のo.eatFood()を呼び出せますか? –