gpt4 book ai didi

java - 具有重复超时的线程(停止超时并在事件发生后重置它)

转载 作者:行者123 更新时间:2023-12-01 08:49:03 25 4
gpt4 key购买 nike

如果系统一段时间没有停止以便稍后能够重置,我需要一个超时(继续代码)的系统。

我的问题是,当我同步到 Map 时,它允许我检查某个键是否存在,但是当我完成并清理内容时,线程已经检查了它是否已被清理。当然,如果其中任何一个有意义,则意味着该线程认为我在需要清理它时没有清理它。

这应该允许我在检查之前暂停清理线程,然后重置超时并在完成后继续检查。

我对多线程非常陌生,希望有任何东西可以为我指明正确的方向(需要阅读的内容以帮助解决此问题等)。我不知道从哪里开始,也不知道有什么可以实现这一目标。

代码示例(希望这是有意义的:))

TestLock lock = new TestLock();
//The lock would get stored with other data See Below: Foo data = map.get("foo");
new Thread()
{
@Override
public void run()
{
//Simply holds idle until the lock timesout.
lock.waitForTimeout(TimeUnit.MILISECONDS, 500); //Timeout is half a second
//Code can continue here if the lock hasn't got reset by the time it times out.
//Timeout will not countdown while it's stopped. See Below: code.getTimeoutLock().stop();
//Check if item is in map and cleanup
}
}.start();
//Somewhere else in the main thread
Foo data = map.get("foo"); //Holds the lock for cleanup
if (data != null)
{
//Stopping the lock can happen at any time to cancel timeout.
data.getTimeoutLock().stop(); //Stop the lock timeout
//Do my stuff
//This is where the thread would check if I removed the data object.
if (foo) //Random if that may or may not be true
{
map.remove("foo"); //Cleanup myself
}
data.getTimeoutLock().reset(); //Reset the lock timeout to what was set and continue timeout.
}

最佳答案

简单的映射不适合并发访问/同步。您至少需要一个 synchronized mapConcurrentHashMap 。但这对于测试和设置场景(例如“如果键不存在则放置键/值”)来说仍然不够,因为只有单个操作(例如 contains())是线程安全的。在 contains()put() 之间,另一个线程可能会访问该映射并使 contains() 调用的结果无效。因此,您将需要另一把锁。示例:

public class MapSample {

private final Object lock = new Object();

public void doSomething() {
// Do not access/edit map except for simple read operations

synchronized(lock) {
// access/edit map…
}

// Do not access/edit map except for simple read operations
}
}

但是因为你等待某事发生,我认为 CountDownLatch将是一个更明智的解决方案:

public class LatchSample {

private final CountDownLatch latch = new CountDownLatch(1);

public void doSomething() {
// do something
// signal completion after you did what you had to do
latch.countDown();
}

public void doSomethingAfterCompletion() {
// will block until countDown() is called
latch.await();
}
}

如果您必须重复等待,请使用 CyclicBarrier .

推荐阅读:Java Concurrency in Practice

关于java - 具有重复超时的线程(停止超时并在事件发生后重置它),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42503765/

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