Future.cancel(boolean)方法的实用程序 [英] Utility of Future.cancel(boolean) method

查看:145
本文介绍了Future.cancel(boolean)方法的实用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是在探索java.util.concurrent包.

I was simply exploring the java.util.concurrent package.

我了解到,"未来"类具有方法布尔值取消(布尔值mayInterruptIfRunning)

I learnt that the class 'Future' has a method boolean cancel(boolean mayInterruptIfRunning)

请在附件中找到我编写的测试代码:

Please find attached the test code I wrote :

package com.java.util.concurrent;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;

public class FutureTester {

/**
 * @param args
 * @throws InterruptedException
 */
public static void main(String[] args) throws InterruptedException {
    // TODO Auto-generated method stub
    int poolCnt = 1;
    Callable<NumberPrinter> numberPrinter = null;
    ScheduledThreadPoolExecutor schPool = new ScheduledThreadPoolExecutor(
            poolCnt);
    ScheduledFuture<NumberPrinter>[] numPrinterFutures = new ScheduledFuture[poolCnt];
    FutureTask<NumberPrinter>[] futureTask = new FutureTask[poolCnt];

    for (int i = 0; i < poolCnt; i++) {
        numberPrinter = new NumberPrinter();
        futureTask[i] = new FutureTask<NumberPrinter>(numberPrinter);

        /*
         * numPrinterFutures[i] = (ScheduledFuture<NumberPrinter>) schPool
         * .schedule(futureTask[i], 0, TimeUnit.MILLISECONDS);
         */
        numPrinterFutures[i] = (ScheduledFuture<NumberPrinter>) schPool
                .submit(futureTask[i]);
    }

    //Thread.sleep(30);

    if (numPrinterFutures.length > 0) {

        System.out.println("Task completed ? "
                + numPrinterFutures[0].isDone());

        System.out.println("Task cancelled ? "
                + numPrinterFutures[0].cancel(true));

        System.out.println("Is task cancelled ? "
                + numPrinterFutures[0].isCancelled());
    }
}

}

class NumberPrinter implements Callable<NumberPrinter> {

private int counter = 10;

@Override
public NumberPrinter call() throws Exception {
    // TODO Auto-generated method stub

    while (counter > 0) {
        if (Thread.interrupted()) {/*OUCH !!!*/
            return null;
        }
        System.out.println("counter = " + (counter--));
    }

    return this;
}

}

最初,我以为取消任务也会停止正在运行的线程的执行( 不包括"OUCH"部分 ).但是我得到的输出为如下:

Intially,I assumed that cancelling a task will also stop the execution of a running thread(the 'OUCH' part NOT included).But I got the output as follows :

counter = 10
Task completed ? false
counter = 9
Task cancelled ? true
counter = 8
Is task cancelled ? true
counter = 7
counter = 6
counter = 5
counter = 4
counter = 3
counter = 2
counter = 1

在进一步阅读stackoverflow本身时,据说

On further reading on stackoverflow itself,it was said that

  1. 取消"方法只能停止未启动"作业(这与该方法的api描述相反)
  2. cancel方法只是中断正在运行的线程,然后 必须从run()方法返回
  1. The 'cancel' method can only stop the 'unstarted' jobs(which contradicts with the api description of the method)
  2. The cancel method simply interrupts the running thread which then must return from the run() method

因此,我包括了"OUCH"部分-while循环检查是否中断 ;输出如下:

Hence,I included the 'OUCH' part - a while loop checking for interruption;the output was as follows :

Task completed ? false
counter = 10
Task cancelled ? true
Is task cancelled ? true

问题:

如果应该编写类似于"OUCH"部分的内容来停止正在运行的线程,则cancel方法的实用程序/值是什么.如果无法通过取消停止线程,则在FutureTask中包装Callable有什么帮助?我要忽略的设计/概念/逻辑部分是什么?

推荐答案

您忽略的问题是,只有协作线程才能在Java中安全停止.

The problem that you are overlooking is that only cooperating threads can be stopped safely in Java.

实际上,如果您查看Thread API,您会注意到Java 1.1中不推荐使用某些名为destroypausestopresume的方法.不推荐使用它们的原因是Java设计人员意识到它们通常不能安全使用.原因在注释为什么是Thread.stop,Thread.suspend和Thread.resume是否已弃用?" .

Indeed, if you look at the Thread API, you will notice that there are some methods called destroy, pause, stop, and resume that were deprecated in Java 1.1. The reason that they were deprecated is that the Java designers realized that they generally can't be used safely. The reasons are explained in the note "Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?".

该问题是Java线程模型所固有的,只能通过减少一个线程与其他线程使用的对象进行交互的能力来避免.有一个JSR指定了一种执行此操作的方法...隔离...但据我所知,没有主流JVM实现这些API.

The problem is inherent in the Java threading model, and could only be avoided by curtailing the ability of one thread to interact with objects used by other threads. There is a JSR that specifies one one way of doing this ... Isolates ... but no mainstream JVMs implement these APIs to my knowledge.

因此,将其带回您的问题,Future.cancel的用处在于它解决了在期货背景下可以解决 的问题的子集.

So bringing this back to your question, the usefulness of Future.cancel is that it solves the subset of the problem that can be solved in the context of futures.

这篇关于Future.cancel(boolean)方法的实用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆