Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ForkJoinPool重置线程中断状态_Java_Multithreading_Java.util.concurrent_Forkjoinpool - Fatal编程技术网

Java ForkJoinPool重置线程中断状态

Java ForkJoinPool重置线程中断状态,java,multithreading,java.util.concurrent,forkjoinpool,Java,Multithreading,Java.util.concurrent,Forkjoinpool,我只是在取消由返回的未来时注意到以下现象。给出以下示例代码: ForkJoinPool pool = new ForkJoinPool(); Future<?> fut = pool.submit(new Callable<Void>() { @Override public Void call() throws Exception { while (true) { if (Thread.currentThread().isInterrupt

我只是在取消由返回的未来时注意到以下现象。给出以下示例代码:

ForkJoinPool pool = new ForkJoinPool();
Future<?> fut = pool.submit(new Callable<Void>() {

  @Override
  public Void call() throws Exception {
    while (true) {
      if (Thread.currentThread().isInterrupted()) { // <-- never true
        System.out.println("interrupted");
        throw new InterruptedException();
      }
    }
  }
});

Thread.sleep(1000);
System.out.println("cancel");
fut.cancel(true);
ForkJoinPool-pool=新的ForkJoinPool();
Future fut=pool.submit(新的可调用(){
@凌驾
public Void call()引发异常{
while(true){

如果(Thread.currentThread().isInterrupted()){/发生这种情况是因为
Future
是一个
ForkJoinTask.AdaptedCallable
扩展了
ForkJoinTask
,其取消方法是:

public boolean cancel(boolean mayInterruptIfRunning) {
    return setCompletion(CANCELLED) == CANCELLED;
}

private int setCompletion(int completion) {
    for (int s;;) {
        if ((s = status) < 0)
            return s;
        if (UNSAFE.compareAndSwapInt(this, statusOffset, s, completion)) {
            if (s != 0)
                synchronized (this) { notifyAll(); }
            return completion;
        }
    }
}
public boolean cancel(boolean可能中断frunning){
返回设置完成(取消)=取消;
}
私有整数集完成(整数完成){
对于(int s;;){
如果((s=状态)<0)
返回s;
如果(不安全。比较数据(此、状态偏移、s、完成)){
如果(s!=0)
已同步(此){notifyAll();}
返回完成;
}
}
}

它不做任何中断,只是设置状态。我想这是因为
ForkJoinPools
未来可能有一个非常复杂的树结构,并且不清楚取消它们的顺序。

在@Mkhail答案上分享更多信息:

使用ForkJoinPool execute()而不是submit()将强制失败的Runnable抛出工作异常,此异常将被线程UncaughtExceptionHandler捕获

摘自Java 8代码:
提交正在使用AdaptedRunnableAction()。
execute正在使用RunnableExecuteAction()(请参阅重试(ex)

/**
*无结果的可运行适配器
*/
静态最终类AdaptedRunnableAction扩展了ForkJoinTask
实现可运行未来{
最终可运行;
AdaptedRunnableAction(可运行可运行){
如果(runnable==null)抛出新的NullPointerException();
this.runnable=runnable;
}
public final Void getRawResult(){return null;}
公开最终作废setRawResult(作废v){}
public final boolean exec(){runnable.run();返回true;}
公共最终无效运行(){invoke();}
私有静态最终长serialVersionUID=52324539592276885070L;
}
/**
*用于可运行的适配器,在该适配器中,故障强制工作异常
*/
静态最终类RunnableExecuteAction扩展了ForkJoinTask{
最终可运行;
RunnableExecuteAction(Runnable-Runnable){
如果(runnable==null)抛出新的NullPointerException();
this.runnable=runnable;
}
public final Void getRawResult(){return null;}
公开最终作废setRawResult(作废v){}
public final boolean exec(){runnable.run();返回true;}
无效异常(可丢弃的ex){
rethrow(ex);//在exec()捕获之外重试。
}
私有静态最终长serialVersionUID=52324539592276885070L;
}

BTW,为什么要在这个案例中使用FJP?@Mikhail这只是我们用例的一个非常小的示例。我们在可调用函数中启动了一些递归操作,这些操作在ForkJoinTask.getPool()上被调用感谢Mikhail的调查。看起来无法从Callable中检查取消。我需要提交一个ForkJoinTask并调用isCancelled(),这很糟糕,因为您总是需要传递对ForkJoinTask的引用来检查取消
 /**
 * Adaptor for Runnables without results
 */
static final class AdaptedRunnableAction extends ForkJoinTask<Void>
    implements RunnableFuture<Void> {
    final Runnable runnable;
    AdaptedRunnableAction(Runnable runnable) {
        if (runnable == null) throw new NullPointerException();
        this.runnable = runnable;
    }
    public final Void getRawResult() { return null; }
    public final void setRawResult(Void v) { }
    public final boolean exec() { runnable.run(); return true; }
    public final void run() { invoke(); }
    private static final long serialVersionUID = 5232453952276885070L;
}

/**
 * Adaptor for Runnables in which failure forces worker exception
 */
static final class RunnableExecuteAction extends ForkJoinTask<Void> {
    final Runnable runnable;
    RunnableExecuteAction(Runnable runnable) {
        if (runnable == null) throw new NullPointerException();
        this.runnable = runnable;
    }
    public final Void getRawResult() { return null; }
    public final void setRawResult(Void v) { }
    public final boolean exec() { runnable.run(); return true; }
    void internalPropagateException(Throwable ex) {
        rethrow(ex); // rethrow outside exec() catches.
    }
    private static final long serialVersionUID = 5232453952276885070L;
}