Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.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 在callables线程上使用invokeAll和timeout的ExecutorService在超时异常后未终止_Java_Multithreading_Timeout_Threadpool_Executorservice - Fatal编程技术网

Java 在callables线程上使用invokeAll和timeout的ExecutorService在超时异常后未终止

Java 在callables线程上使用invokeAll和timeout的ExecutorService在超时异常后未终止,java,multithreading,timeout,threadpool,executorservice,Java,Multithreading,Timeout,Threadpool,Executorservice,我试图在线程上设置一个超时,并期望执行器抛出异常,阻止线程运行,从而终止它,但超时工作不会找到这种情况 但是线程确实完成了执行。 如果线程超过超时时间,如何终止线程? 这是我的测试代码: class ArithmeticBB implements ArithmeticManagerCallable.ArithmeticAction { @Override public String arithmetic(String n) { try {

我试图在线程上设置一个超时,并期望执行器抛出异常,阻止线程运行,从而终止它,但超时工作不会找到这种情况 但是线程确实完成了执行。 如果线程超过超时时间,如何终止线程? 这是我的测试代码:

class ArithmeticBB implements ArithmeticManagerCallable.ArithmeticAction {
    @Override
    public String arithmetic(String n) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String ss  = n+" 2" + " ,Thread ID:" +Thread.currentThread().getId();
        return ss;
    }
}
public class ArithmeticManagerCallable {
    ExecutorService executor = null;
    private List<String> integerList = null;
    private List<String> myResult= Collections.synchronizedList(new ArrayList<>());
    private int threadTimeOutInSec = 180;

    public ArithmeticManagerCallable(List<String> dataFromUser, int poolSize, int threadTimeOutInSec) {
        this.integerList =  dataFromUser;
        executor = Executors.newFixedThreadPool(poolSize);
        this.threadTimeOutInSec = threadTimeOutInSec;
    }
    private void exec(ArithmeticAction arithmeticAction) {
        List<String> tempList = new ArrayList<>();
        for(Iterator<String> iterator = integerList.listIterator(); iterator.hasNext();) {
            tempList.add(arithmeticAction.arithmetic(iterator.next()));
        }
        resultArray.addAll(tempList);
    }
    public List<String> invokerActions(List<ArithmeticAction> actions) throws
            InterruptedException {

        Set<Callable<String>> callables = new HashSet<>();
        for (final ArithmeticAction ac : actions) {
            callables.add(new Callable<String>() {
                public String call() throws Exception{
                    exec(ac);
                    return "done";
                }
            });
        }
        List<Future<String>> futures = executor.invokeAll(callables, this.threadTimeOutInSec, TimeUnit.SECONDS);
        executor.shutdown();
        while (!executor.isTerminated()) {
        }
        return myResult;
    }
    public interface ArithmeticAction {
        String arithmetic(String n);
    }

    public static void main(String[] args) {
        List<ArithmeticManagerCallable.ArithmeticAction> actions = new ArrayList();
        actions.add(new ArithmeticBB());
        List<String> intData = new ArrayList<>();
        intData.add("1");

        ArithmeticManagerCallable arithmeticManagerCallable = new ArithmeticManagerCallable(intData,20,4);

        try {
            List<String> result = arithmeticManagerCallable.invokerActions(actions);
            System.out.println("***********************************************");
            for(String i : result) {
                System.out.println(i);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
类ArithmeticBB实现ArithmeticManagerCallable.ArithmeticAction{
@凌驾
公共字符串算术(字符串n){
试一试{
睡眠(5000);
}捕捉(中断异常e){
e、 printStackTrace();
}
字符串ss=n+“2”+,线程ID:“+Thread.currentThread().getId();
返回ss;
}
}
公共类算术管理器可调用{
executor服务executor=null;
私有列表整数列表=null;
私有列表myResult=Collections.synchronizedList(新的ArrayList());
私有int-threadtimeoutinesec=180;
公共算术管理器可调用(列出dataFromUser、int poolSize、int threadTimeOutInSec){
this.integerList=dataFromUser;
executor=Executors.newFixedThreadPool(池大小);
this.threadtimeoutinesec=threadtimeoutinesec;
}
私有void exec(算术动作算术动作){
List templast=new ArrayList();
for(Iterator Iterator=integerList.listIterator();Iterator.hasNext();){
add(arithmetricaction.arithmetric(iterator.next());
}
resultArray.addAll(圣殿骑士);
}
公共列表调用操作(列表操作)抛出
中断异常{
Set callables=newhashset();
用于(最终算术动作ac:动作){
add(newcallable()){
公共字符串调用()引发异常{
行政主任(ac);
返回“完成”;
}
});
}
List futures=executor.invokeAll(可调用项,this.threadtimeoutinesec,TimeUnit.SECONDS);
executor.shutdown();
而(!executor.isTerminated()){
}
返回我的结果;
}
公共接口算术动作{
字符串算术(字符串n);
}
公共静态void main(字符串[]args){
列表操作=新建ArrayList();
添加(新的算术BB());
List intData=new ArrayList();
intData.添加(“1”);
ArtihmeticManagerCallable ArtihmeticManagerCallable=新的ArtihmeticManagerCallable(intData,20,4);
试一试{
列表结果=ArtihmeticManagerCallable.invokerActions(操作);
System.out.println(“**********************************************************************”);
for(字符串i:结果){
系统输出打印LN(i);
}
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}

您的
线程
在超过超时后未完成执行

请看以下示例以供参考:

ExecutorService ExecutorService=Executors.newFixedThreadPool(20);
List callableList=new ArrayList();
对于(int i=0;i<10;i++){
最终int标识符=i;
callableList.add(()->{
试一试{
线程睡眠(1000*标识符);
}捕捉(中断异常e){
System.out.println(“我是“+identifier+”,我的睡眠被中断了。”);
}
返回标识符+“Hello World”;
});
}
试一试{
List futureList=executorService.invokeAll(callableList,5,时间单位为秒);
用于(未来结果:未来列表){
System.out.println(result.get());
}
}捕获(中断异常|执行异常e){
System.out.println(“执行时出错。这可能有帮助:”+e.getMessage());
}捕获(取消异常e){
不是所有的期货都能收到;
}最后{
executorService.shutdown();
}

谢谢,我还连线了一件事,即永远不会从executorService抛出TimeoutException,我如何才能识别它是timeout?来自线程的中断异常。睡不着觉了吗self@user63898
invokeAll
不会抛出
TimeoutException
。如果您想知道future在完成执行之前是否超时,则必须通过其第二个get方法直接询问future。->
vget(longtimeout,TimeUnit)
我喜欢从类型TimeoutException捕获异常,这样我就有了指示器。我注意到我是这样做的:executor.submit(new Callable(){public String call()抛出异常{exec(ac);返回“done”;});它确实从TimeoutException中抛出了正确的异常invokeAll和逐个提交之间的区别是什么?@user63898简单地说:这是两种不同的实现方式
invokeAll
允许您一次提交多个可调用的
。如果您现在通过
invokeAll
执行它们或逐个提交它们,这取决于作为开发人员的您。谢谢,我喜欢调用不阻塞的东西