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

Tho*_*mas 5 java multithreading nonblocking thread-safety

我想调用add具有一些延迟的HashSet函数,但不阻塞当前线程.是否有一个简单的解决方案来实现这样的事情:

Utils.sleep(1000, myHashSet.add(foo)); //added after 1 second
//code here runs immediately without delay
...
Run Code Online (Sandbox Code Playgroud)

Ral*_*pin 10

普通的香草解决方案是:

    new Thread( new Runnable() {
        public void run()  {
            try  { Thread.sleep( 1000 ); }
            catch (InterruptedException ie)  {}
            myHashSet.add( foo );
        }
    } ).start();
Run Code Online (Sandbox Code Playgroud)

幕后花絮比使用ThreadPoolExecutor要少得多.TPE可以很方便地控制线程的数量,但是如果你正在关闭许多休眠或等待的线程,那么限制它们的数量可能会比它的帮助更多地损害性能.

myHashSet如果你还没有处理过,你想要同步.请记住,你必须在任何地方同步才能做到这一点.还有其他方法可以处理这个问题,比如Collections.synchronizedMap或ConcurrentHashMap.

  • Thread.sleep() 是一个阻塞调用。创建一个新线程不会阻塞主线程,但在并行进程中它仍然会阻塞线程。 (4认同)

Tud*_*dor 9

您可以使用ScheduledThreadPoolExecutor.schedule

ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);

exec.schedule(new Runnable() {
          public void run() {
              myHashSet.add(foo);
          }
     }, 1, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)

它将在 1 秒后在单独的线程上执行您的代码。小心myHashSet虽然的并发修改。如果您同时从不同的线程修改集合或尝试对其进行迭代,您可能会遇到麻烦并且需要使用锁。