gpt4 book ai didi

java - 进行预定的调用以再运行一次

转载 作者:行者123 更新时间:2023-12-01 15:05:12 24 4
gpt4 key购买 nike

我们有一个每 10 秒运行一次的计划任务和一个包含 3 个线程的线程池,这些线程实际上更新静态公共(public)映射。计划的操作每 10 秒打印一次该 map 。问题是我希望调度程序在 3 个线程完成 map 后停止打印。但这是关键。我不想立即停止调度程序,我想先打印( map 的最终版本),然后完成。

public class myClass implements ThreadListener {
public static ArrayList<Pair<String, Integer>> wordOccurenceSet = new ArrayList<Pair<String, Integer>>();
int numberOfThreads = 0;
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public void getAnswer(Collection<CharacterReader> characterReaders, Outputter outputter) {




ExecutorService executor = Executors.newFixedThreadPool(characterReaders.size());
OutputterWriteBatch scheduledThread = new OutputterWriteBatch(outputter,wordOccurenceSet);

scheduler.scheduleAtFixedRate(scheduledThread, 10, 10, TimeUnit.SECONDS);
for (CharacterReader characterReader : characterReaders) {
NotifyingRunnable runnable = new CharacterReaderTask(characterReader, wordOccurenceSet);
runnable.addListener(this);

executor.execute(runnable);
}



}


@Override
public void notifyRunnableComplete(Runnable runnable) {
numberOfThreads += 1;
if(numberOfThreads == 3 ){
//All threads finished... What can I do to terminate after one more run?
}
}
}

监听器实际上只是在线程结束时收到通知。

最佳答案

首先,使您的 numberOfThreads 同步。当两个 Reader 线程同时完成时,您不希望它被损坏。它是一个原始 int,因此它可能不会被破坏(我对 JVM 不太精通),但无论如何都应该遵循线程安全的一般规则。

// 1. let finish OutputterWriteBatch if currently running
scheduler.shutdown();
// 2. will block and wait if OutputterWriteBatch was currently running
scheduler.awaitTermination(someReasonableTimeout);
// 3. one more shot.
scheduler.schedule(scheduledThread,0);
// You could also run it directly if your outputting logic in run()
// is published via separate method, but i don't know the API so i suppose
// only Runnable is published

但是当然,这不应该直接从 notifyRunnableComplete 调用。监听器方法是从您的 Reader 线程中调用的,因此它会阻止 3 个线程中的最后一个线程及时完成。而是创建一个通知对象,其他线程将在其上 wait()(最好是执行 getAnswer() 的线程),notify() 它当numberOfThreads达到3时,将上述代码放在wait()后面。

哦,当 wait() 解除阻塞时,您应该仔细检查 numberOfThreads 是否确实为 3,如果不是,则循环回 wait().谷歌“虚假唤醒”来解释为什么需要这样做。

关于java - 进行预定的调用以再运行一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13057202/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com