我想调用一个HashSet的add
函数有一些延迟,但没有阻塞当前线程。有没有简单的解决方案来实现这样的事情:如何使延迟非阻塞函数调用
Utils.sleep(1000, myHashSet.add(foo)); //added after 1 second
//code here runs immediately without delay
...
我想调用一个HashSet的add
函数有一些延迟,但没有阻塞当前线程。有没有简单的解决方案来实现这样的事情:如何使延迟非阻塞函数调用
Utils.sleep(1000, myHashSet.add(foo)); //added after 1 second
//code here runs immediately without delay
...
您可以使用ScheduledThreadPoolExecutor.schedule:
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
exec.schedule(new Runnable() {
public void run() {
myHashSet.add(foo);
}
}, 1, TimeUnit.SECONDS);
它将在一个单独的线程在1秒钟后执行代码。尽管如此,请注意myHashSet
的并发修改。如果您从另一个线程同时修改集合或尝试迭代它,则可能会遇到问题,并且需要使用锁。
的单纯功能的解决办法是:
new Thread(new Runnable() {
public void run() {
try { Thread.sleep(1000); }
catch (InterruptedException ie) {}
myHashSet.add(foo);
}
}).start();
有少了很多比的ThreadPoolExecutor怎么回事幕后。 TPE可以方便地控制线程的数量,但是如果您正在分离大量睡眠或等待的线程,那么限制其数量可能会损害性能,而不仅仅是帮助。
如果您尚未处理此问题,并且您想同步myHashSet
。请记住,你必须同步无处不在为此做任何好事。还有其他的方法来处理这个问题,比如Collections.synchronizedMap或者ConcurrentHashMap。
您的问题的直接答案如下。但是,试图做什么似乎相当不自然,这表明也许你应该寻找一个完全不同的解决方案。你想提供一些更多的上下文,为什么你想延迟添加? – Jochen
我正在使用[Storm](https://github.com/nathanmarz/storm)来实现爬虫。抓取的URL由包含线程ID和板号的模式生成。抓取工具的性质使得每个电路板只能处理一个URL。我的HashSet包含当前可以抓取的所有主板的ID。对单个网址的抓取可能因为不同的原因而失败(线程被删除,404,...)。有些原因允许重试抓取。关于这些原因的信息被保存在不锁定的DB中,所以在决定是否重试之前应该有一些延迟。 – Thomas
这听起来不必要的复杂。为什么爬网线程无法处理返回值,并且在发生可恢复故障时直接重试,或者至少将URL添加回地图(队列可能更适合此操作)。 – Jochen