首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何修复由: concurrent.ExecutionException引起的java.lang.UnsupportedOperationException

如何修复由: concurrent.ExecutionException引起的java.lang.UnsupportedOperationException
EN

Stack Overflow用户
提问于 2019-10-15 05:11:38
回答 1查看 7.4K关注 0票数 0

我发布了一个关于野蛮强制CodeReview的问题,一个好的专家帮助我解决了问题,建议我应该使用多线程来提高程序的速度。他给出的代码很好,提高了速度,但对我来说仍然很慢,所以我更多地研究多线程,并找到了好的文章示例。我复制了一个我理解的例子,为了满足我的需要,我做了很少的修改。这段代码工作得很好,直到我深入阅读了有关多线程的内容,并遇到了invokeAny(),我试图实现它,因此,由于某种未知的原因,它给我带来了错误。我只想获得使用invokeAny找到解析ID的第一个任务,因为程序现在运行得很快。

代码语言:javascript
运行
复制
Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException: Not supported yet.
at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
at java.base/java.util.concurrent.AbstractExecutorService.doInvokeAny(AbstractExecutorService.java:199)
at java.base/java.util.concurrent.AbstractExecutorService.invokeAny(AbstractExecutorService.java:220)
at pait.SiimpleeThreadPool.main(SiimpleeThreadPool.java:31)
Caused by: java.lang.UnsupportedOperationException: Not supported yet.
at pait.WorkerThread.call(WorkerThread.java:73)
at pait.WorkerThread.call(WorkerThread.java:15)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)

代码语言:javascript
运行
复制
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.awt.Label;
import java.util.Random;
import java.util.concurrent.Callable;
public class SimpleThreadPool {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(3);
        int s = 135000000;
        int e = 200000000;
        List<Callable<String>> callList = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Callable worker = new WorkerThread("" + i, s, e);
            callList.add(worker);
            s = s + 15520000;
        }
        String result = executor.invokeAny(callList);
        System.out.println(result);
        executor.shutdown();
        while (!executor.isTerminated()) {
        }
        System.out.println("Finished all threads");
    }

}

代码语言:javascript
运行
复制
public class WorkerThread implements Callable {

    private final  String command;
    private final int start;
    private final int end;
    private final Label lb = new Label();

    public WorkerThread(String s, int start, int end) {
        this.command = s;
        this.start = start;
        this.end = end;
    }

    public void run() {
        processCommand(start, end);

    }

    private void processCommand(int start, int end) {
        for (int i = start; i < end; i++) {
            Random rand= new Random(i);
            long pair = rand.nextInt();
            if (pair == 739619665) {
                System.out.println(start + "     " + end + "        Executing Task inside : " + Thread.currentThread().getName());
                System.out.println(i);
                lb.setText("Stop");
                break;
            }
        }
    }

    ;

    @Override
    public String call() throws Exception {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public String toString() {
        return this.command;
    }

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-15 08:16:40

为什么是UnsupportedOperationException

您的WorkerThread类实现了Callable接口,即:

返回结果并可能引发异常的任务。实现者定义一个没有名为call的参数的方法。

使用Callable实现(如ExecutorService#invokeAny(Collection) )的API将调用call方法,这意味着实际工作需要在said call方法中实现。但是,您的代码如下:

代码语言:javascript
运行
复制
@Override
public String call() throws Exception {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

这就是为什么您要得到一个UnsupportedOperationException,因为这正是该方法所要做的。要解决这个问题,只需正确地实现该方法。你还拥有:

代码语言:javascript
运行
复制
public void run() {
    processCommand(start, end);

}

这让我认为,您要么混淆了RunnableCallable接口,要么混淆了用于实现RunnableWorkerThread类,并且在切换到Callable时忘记了完全更新代码。假设processCommand是任务的实际工作,那么call方法应该如下所示:

代码语言:javascript
运行
复制
@Override
public String call() throws Exception {
    processCommand(start, end);
    return "I don't know what's supposed to be returned";
}

您可以删除run方法。

等待终止

您不应该在等待ExecutorService终止时旋转:

代码语言:javascript
运行
复制
while (!executor.isTerminated()) {
}

该接口提供了一种在ExecutorService终止之前阻塞的方法,这种方法通常更友好:ExecutorService#awaitTermination(long,TimeUnit)。该方法接受一个超时值,以指定线程应阻塞等待终止的最大时间量。如果您想“永远”等待,请使用一个非常大的值,例如:

代码语言:javascript
运行
复制
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);

避免生料类型

我建议阅读什么是原始类型,我们为什么不使用它?Callable接口是通用的,但是在某些地方使用的是原始类型。而不是拥有:

代码语言:javascript
运行
复制
public class WorkerThread implements Callable {...}
// and
Callable worker = new WorkerThread(...);

你应该:

代码语言:javascript
运行
复制
public class WorkerThread implements Callable<String> {...}
// and
Callable<String> worker = new WorkerThread<>(...);

UI线程

注意,您有一个java.awt.Label,它正在processCommand方法中更新。请记住,UI对象通常只能在UI线程上访问(例如,Swing中的事件调度线程())。至少,Swing是这样的--我不确定AWT是否线程安全。尽管如此,我并不确定您为什么要使用Label,因为您的代码似乎都与GUI无关。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58387614

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档