如何进行延迟的非阻塞函数调用

我想调用具有一些延迟的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。

检查ThreadPoolExecutor.schedule()方法。