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

时间:2014-08-02 11:04:05

标签: java servlets runnable callable

我在使用runnable接口将代码转换为以下代码中的可调用接口时遇到问题。我需要改变,因为我需要通过线程返回Sting[][] isR个。

当我将界面更改为callablechande .run()更改为.call()时,new Thread(new Worker(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) {

}

2 个答案:

答案 0 :(得分:4)

您无法将Callable传递给Thread来执行。

使用ExecutorService执行Callable对象。

您可以使用Callable方法运行submit()个对象:

<T> Future<T> submit(Callable<T> task)

你的课应该是这样的:

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();
            }
        };
    }

}

你可以这样开始:

    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);
    }

并且,获取并打印结果字符串:

    for(Future<String[][]> future : set){
        String[][] result = future.get();
        for (String[] strArr: result){
            for (String str: strArr){
                System.out.println(str);
            }
        }
    }

但这种设计可以改进。请查看Callable上的以下文档,了解它与Runnable的区别,以及如何从这些差异中获得优势并正确实施:

Interface Callable

https://blogs.oracle.com/CoreJavaTechTips/entry/get_netbeans_6?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+corejavatechtips+(Core+Java+Technologies+Tech+Tips)

另请查看此链接,我根据您可以运行的代码编写了一个示例:http://ideone.com/blUQm0

答案 1 :(得分:1)

一旦你的类实现了可调用的接口,你就会有方法调用并且它有返回类型。

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

ExecutorService service =  Executors.newSingleThreadExecutor();
Worker worker= new Worker (tartSignal, doneSignal,threadNumber);
Future<Integer> future = service.submit(worker);
Object result = future.get();

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