繁体   English   中英

从 Runnable 返回一个值

[英]Returning a value from Runnable

Runnablerun方法的返回类型为void ,不能返回值。 但是,我想知道是否有任何解决方法。

我有一个这样的方法:

public class Endpoint {
    public method() {
       Runnable runcls = new RunnableClass();
       runcls.run()
    }
}

方法run是这样的:

public class RunnableClass implements Runnable {
    
    public JaxbResponse response;

    public void run() {
        int id = inputProxy.input(chain);
        response = outputProxy.input();
    }
}

我想访问method response变量。 这可能吗?

使用Callable<V>而不是使用Runnable接口。

例子:

public static void main(String args[]) throws Exception {
    ExecutorService pool = Executors.newFixedThreadPool(3);
    Set<Future<Integer>> set = new HashSet<>();

    for (String word : args) {
      Callable<Integer> callable = new WordLengthCallable(word);
      Future<Integer> future = pool.submit(callable);
      set.add(future);
    }

    int sum = 0;
    for (Future<Integer> future : set) {
      sum += future.get();
    }

    System.out.printf("The sum of lengths is %s%n", sum);
    System.exit(sum);
}

在此示例中,您还需要实现类WordLengthCallable ,该类实现了Callable接口。

public void check() {
    ExecutorService executor = Executors.newSingleThreadExecutor();
    Future<Integer> result = executor.submit(new Callable<Integer>() {
        public Integer call() throws Exception {
            return 10;
        }
    });

    try {
        int returnValue = result.get();
    } catch (Exception exception) {
       //handle exception
    }
}

看看Callable类。 这通常是通过执行程序服务提交的

它可以返回一个 future 对象,该对象在线程完成时返回

是的,有解决方法。 只需使用队列并将您想要返回的值放入其中。 并从另一个线程中获取此值。

public class RunnableClass implements Runnable{

        private final BlockingQueue<jaxbResponse> queue;


        public RunnableClass(BlockingQueue<jaxbResponse> queue) {
            this.queue = queue;
        }

        public void run() {
            int id;
            id =inputProxy.input(chain);
            queue.put(outputProxy.input());
        }
    }


    public class Endpoint{
        public method_(){
            BlockingQueue<jaxbResponse> queue = new LinkedBlockingQueue<>();

            RunnableClass runcls = new RunnableClass(queue);
            runcls.run()

            jaxbResponse response = queue.take(); // waits until takes value from queue
        }
    }

如果您向RunnableClass添加一个字段,您可以在run设置它并在method_读取它。 但是, Runnable是一个糟糕的(Java 关键字) interface因为它没有告诉您有关(概念)接口的任何信息(API 文档中仅有用的一行:“ run方法的一般约定是它可以采取任何行动。 ”)。 使用更有意义的接口(可能会返回一些东西)要好得多。

一种方法是,我们必须使用Future - Callable方法。

另一种方法是,您可以在对象中保存而不是返回值

例子:

class MainThread {
    public void startMyThread() {
        Object requiredObject = new Object(); //Map/List/OwnClass
        Thread myThread = new Thread(new RunnableObject(requiredObject)).start();
        myThread.join();

        System.out.println(requiredObject.getRequiredValue());    
    }
}



class RunnableObject implements Runnable {
    private Object requiredObject;

    public RunnableObject(Object requiredObject) {
        this.requiredObject = requiredObject;
    }

    public void run() {
        requiredObject.setRequiredValue(xxxxx);
    }
}

因为对象作用域在同一个作用域内,所以您可以将对象传递给线程并可以在主作用域中检索。 但是,最重要的是,我们必须使用 join() 方法。 因为主作用域应该等待线程完成其任务。

对于多线程情况,您可以使用List / Map来保存来自线程的值。

尝试以下

public abstract class ReturnRunnable<T> implements Runnable {

    public abstract T runForResult();

    @Override
    public void run() {
        runForResult();
    }
}

看看callable interface ,也许这适合您的需求。 您还可以尝试通过在run()方法中调用 setter-method 来获取响应字段的值

public void run() {
    int id;
    id =inputProxy.input(chain);
    response = outputProxy.input();
    OuterClass.setResponseData(response);

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM