在Javaservlet中将Runnable.run()转换为Callable.call()

在Javaservlet中将Runnable.run()转换为Callable.call(),java,servlets,runnable,callable,Java,Servlets,Runnable,Callable,在下面的代码中,我无法将带有可运行接口的代码转换为可调用接口。我需要更改,因为我需要通过线程返回Sting[][]isRs 当我将接口更改为callable和chande.run()为.call(),然后新建线程(新工作线程(startSignal,doneSignal,I)).start()不起作用 CountDownLatch startSignal = new CountDownLatch(1); CountDownLatch doneSignal = new CountDownLatch

在下面的代码中,我无法将带有可运行接口的代码转换为可调用接口。我需要更改,因为我需要通过线程返回
Sting[][]isR
s

当我将接口更改为
callable
chande.run()
.call()
,然后
新建线程(新工作线程(startSignal,doneSignal,I)).start()不起作用

CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(3); // 3 tasks

class Worker implements Runnable {
    private final CountDownLatch startSignal;
    private final CountDownLatch doneSignal;
    private final int threadNumber;

    // you can pass additional arguments as well
    Worker(CountDownLatch startSignal, CountDownLatch doneSignal, int threadNumber) {
        this.startSignal = startSignal;
        this.doneSignal = doneSignal;
        this.threadNumber = threadNumber;
    }

    public void run() {
        try {
            startSignal.await();

            if (threadNumber == 1) {
                String[][] isRs = getIS(erg1, erg2, request);
            }

            if (threadNumber == 2) {
                getIW(erg1, erg2, request);
            }

            if (threadNumber == 3) {
                getIN(search_plz, request);
            }

            doneSignal.countDown();
        } catch (InterruptedException ex) {
            System.out.println(ex);
        }
    }
}

// 3 new threads are started
for (int i = 1; i <= 3; i++) {
    new Thread(new Worker(startSignal, doneSignal, i)).start();
}

startSignal.countDown(); // let all threads proceed
try {
    doneSignal.await(); // wait for all to finish
    // all 3 tasks are finished and do whatever you want to do next
} catch (Exception e) {

}
CountDownLatch startSignal=新的CountDownLatch(1);
CountDownLatch doneSignal=新的CountDownLatch(3);//3项任务
类工作者实现可运行的{
私人最终倒计时闩锁启动信号;
私人最终倒计时信号;
私有最终整数线程数;
//您还可以传递其他参数
辅助程序(CountDownLatch startSignal、CountDownLatch doneSignal、int threadNumber){
this.startSignal=startSignal;
this.doneSignal=doneSignal;
this.threadNumber=threadNumber;
}
公开募捐{
试一试{
开始信号。等待();
if(threadNumber==1){
字符串[][]isRs=getIS(erg1、erg2、request);
}
if(threadNumber==2){
getIW(erg1,erg2,请求);
}
if(threadNumber==3){
getIN(搜索、请求);
}
doneSignal.countDown();
}捕获(中断异常例外){
系统输出打印项次(ex);
}
}
}
//启动3个新线程

对于(int i=1;i您不能将
可调用的
传递到
线程
中执行

使用
ExecutorService
执行
Callable
对象

您可以使用它的
submit()
方法为它提供可调用的
对象:

未来提交(可调用任务)

您的类应该如下所示:

class Worker {

    private final CountDownLatch startSignal;
    private final CountDownLatch doneSignal;
    private final int threadNumber;

    Worker(
        CountDownLatch startSignal,
        CountDownLatch doneSignal,
        int threadNumber
    ){

        this.startSignal = startSignal;
        this.doneSignal = doneSignal;
        this.threadNumber = threadNumber;

    }

    public String[][] getSomeStrArrArr() {

        try {

            startSignal.await();

            if (threadNumber == 1) {
                System.out.println("Running thread number 1");
            }

            if (threadNumber == 2) {
                System.out.println("Running thread number 2");
            }

            if (threadNumber == 3) {
                System.out.println("Running thread number 3");
            }

            doneSignal.countDown();

        } catch (InterruptedException ex) {

            System.out.println(
                    "Thread number "+threadNumber+" has been interrupted."
            );

        }

        // replace these 2 lines with the actual code to get the String[][]
        String[][] someStrArrArr = new String[1][1];
        someStrArrArr[0][0] = "Done with thread number "+threadNumber;

        return someStrArrArr;

    }

    public Callable<String[][]> getSomeCallableStrArrArr(){
        return new Callable<String[][]>() {
            public String[][] call() throws Exception {
                return getSomeStrArrArr();
            }
        };
    }

}
类工作者{
私人最终倒计时闩锁启动信号;
私人最终倒计时信号;
私有最终整数线程数;
工人(
倒计时闩锁启动信号,
倒计时信号,
整数线程数
){
this.startSignal=startSignal;
this.doneSignal=doneSignal;
this.threadNumber=threadNumber;
}
公共字符串[][]GetSomeStrarrr(){
试一试{
开始信号。等待();
if(threadNumber==1){
System.out.println(“运行线程编号1”);
}
if(threadNumber==2){
System.out.println(“运行线程编号2”);
}
if(threadNumber==3){
System.out.println(“运行线程编号3”);
}
doneSignal.countDown();
}捕获(中断异常例外){
System.out.println(
“螺纹编号”+螺纹编号+“已中断。”
);
}
//用实际代码替换这两行以获取字符串[][]
字符串[][]somestrarrar=新字符串[1][1];
someStrArrArr[0][0]=“使用线程编号完成”+线程编号;
返回somestrarrar;
}
公共可调用getSomeCallableStrarrr(){
返回新的可调用(){
公共字符串[][]调用()引发异常{
返回getSomeStrarrr();
}
};
}
}
你可以这样开始:

    ExecutorService pool = Executors.newFixedThreadPool(3);
    Set<Future<String[][]>> set = new HashSet<Future<String[][]>>();
    CountDownLatch startSignal = new CountDownLatch(1);
    CountDownLatch doneSignal = new CountDownLatch(3);
    for (int i=1;i<=3;i++) {
        Worker worker = new Worker(startSignal,doneSignal,i);
        Callable<String[][]> callable =
                worker.getSomeCallableStrArrArr();
        Future<String[][]> future = pool.submit(callable);
        set.add(future);
    }
ExecutorService池=Executors.newFixedThreadPool(3);
Set=newhashset();
CountDownLatch startSignal=新的CountDownLatch(1);
CountDownLatch doneSignal=新的CountDownLatch(3);

对于(inti=1;i一旦您的类实现了可调用接口,您将拥有方法调用及其返回类型

您可以将以下代码用于ExecutorService:-

ExecutorService service =  Executors.newSingleThreadExecutor();
Worker worker= new Worker (tartSignal, doneSignal,threadNumber);
Future<Integer> future = service.submit(worker);
Object result = future.get();
ExecutorService service=Executors.newSingleThreadExecutor();
Worker-Worker=新的Worker(tartSignal、doneSignal、threadNumber);
未来=服务。提交(工人);
对象结果=future.get();

希望这将有助于解决您的问题。

不要使用原始线程,请使用
ExecutorService
。或者,更好的是,使用Java 8
CompletableFuture
。如何做到这一点,这是否解决了我的问题?从那里开始并从那里开始工作。我要注意,如果threadNumber==x
,您的
可以通过多态性解决,resulting在更干净的代码中。为什么要将
可运行
更改为
可调用
?此代码非常错误。您的
工作者
未编译。“应该看起来像”与“应该是”不同。如果你想学习一些东西,你必须付出一些努力。为了更清楚,我编辑并替换了代码片段中一些模棱两可的部分。目的是让OP了解所需更改的主要内容,以便使用可调用接口而不是可运行接口;为他指明正确的方向,而不是为h编写代码尽管如此,欢迎你提供一个更好的例子。谢谢你的回答,但是如果我正确理解你的例子,它对我没有帮助。我使用不同线程的原因是,所有3个任务都应该同时处理,因为它们需要一些时间。在你的例子中,它们将被同步处理,因为它们等待返回还是我错了?@BoristheSpider根据我的理解,elcodedocle提供的代码可以很好地解释如何实现逻辑。最终目标是解释用户,以便他能够获得帮助来解决小的编译问题。好的,你完全正确。它是并行的。所以现在我已经设置了3个线程的3个结果?我如何获得t3字符串[][]结果超出设置范围?谢谢。Object result是call()的返回值吗?如何从结果中获取返回的字符串[][]。另一个问题是,我的start和stopSignal不再工作了。好的,start和stopSignal正在工作,但如何获得返回值?在实现可调用的inter之后,在worker类中
ExecutorService service =  Executors.newSingleThreadExecutor();
Worker worker= new Worker (tartSignal, doneSignal,threadNumber);
Future<Integer> future = service.submit(worker);
Object result = future.get();