【问题标题】:How to interrupt BlockingQueue?如何中断 BlockingQueue?
【发布时间】:2013-03-25 04:40:36
【问题描述】:

BlockingQueue.put 可以抛出 InterruptedException。 如何通过抛出此异常导致队列中断?

ArrayBlockingQueue<Param> queue = new ArrayBlockingQueue<Param>(NUMBER_OF_MEMBERS);
...
try {
    queue.put(param);
} catch (InterruptedException e) {
    Log.w(TAG, "put Interrupted", e);
}
...
// how can I queue.notify?

【问题讨论】:

    标签: java android concurrency blocking interrupt


    【解决方案1】:

    您需要中断正在调用queue.put(...); 的线程。 put(...); 调用在某些内部条件下执行wait(),如果调用put(...) 的线程被中断,则wait(...) 调用将抛出InterruptedException,由put(...); 传递

    // interrupt a thread which causes the put() to throw
    thread.interrupt();
    

    要获取线程,您可以在创建时存储它:

    Thread workerThread = new Thread(myRunnable);
    ...
    workerThread.interrupt();
    

    或者您可以使用Thread.currentThread() 方法调用并将其存储在某个地方以供其他人使用来中断。

    public class MyRunnable implements Runnable {
         public Thread myThread;
         public void run() {
             myThread = Thread.currentThread();
             ...
         }
         public void interruptMe() {
             myThread.interrupt();
         }
    }
    

    最后,捕获InterruptedException 立即重新中断线程是一个很好的模式,因为当InterruptedException 被抛出时,线程上的中断状态被清除。

    try {
        queue.put(param);
    } catch (InterruptedException e) {
        // immediately re-interrupt the thread
        Thread.currentThread().interrupt();
        Log.w(TAG, "put Interrupted", e);
        // maybe we should stop the thread here
    }
    

    【讨论】:

      【解决方案2】:

      您需要使用 queue.put() 引用运行代码的线程,就像在这个测试中一样

          Thread t = new Thread() {
              public void run() {
                  BlockingQueue queue = new ArrayBlockingQueue(1);
                  try {
                      queue.put(new Object());
                      queue.put(new Object());
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              };
          };
          t.start();
          Thread.sleep(100);
          t.interrupt();
      

      【讨论】:

        【解决方案3】:

        调用put 将等待一个插槽空闲,然后再添加param 并且流程可以继续。

        如果您在调用put 时捕获正在运行的线程(即,在调用put 之前调用Thread t1 = Thread.currentThread()),然后在另一个线程中调用interrupt(而t1 被阻塞) .

        This example 有类似的东西,它负责在给定超时后调用中断。

        【讨论】:

          猜你喜欢
          • 2010-10-23
          • 1970-01-01
          • 2014-01-25
          • 2010-11-10
          • 2016-07-28
          • 2014-01-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多