web-dev-qa-db-ja.com

java Runnable run()メソッドが値を返す

Java doc、Runnable method void run()によると、値を返すことはできません。しかし、この回避策はあるのでしょうか。

実際に呼び出すメソッドがあります:

_public class Endpoint{
    public method_(){
       RunnableClass runcls = new RunnableClass();
       runcls.run()
    }
}
_

ここで、メソッドrun()は次のとおりです。

_public class RunnableClass implements Runnable{

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

        }
}
_

method_()response変数にアクセスしたいのですが、これは可能ですか?

41
Grzzzzzzzzzzzzz

つかいます Callable<V>Runnableインターフェイスを使用する代わりに。

例:

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

この例では、Callableインターフェイスを実装するクラスWordLengthCallableも実装する必要があります。

55
Narendra Pathai
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
    }
}
14
vishal_aim

Callable クラスをご覧ください。通常、これは executorサービス を介して送信されます

スレッドが完了すると返される将来のオブジェクトを返すことができます

7
RNJ

はい、回避策があります。キューを使用して、返りたい値を入れてください。そして、この値を別のスレッドから取得します。

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
        }
    }
3
Eldar Agalarov

RunnableClassにフィールドを追加する場合、runで設定して、method_。ただし、Runnableは貧弱です(Javaキーワード)interfaceは(概念)インターフェイス(APIの有用な行のみ) docs: "メソッドrunの一般的な契約は、どんなアクションでも実行できるということです。")。より意味のあるインターフェイス(何かを返す可能性がある)を使用する方がはるかに良いです。

1つの方法は、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を使用して、スレッドからの値を保持できます。

2
ramakrishna

以下をお試しください

public abstract class ReturnRunnable<T> implements Runnable {

    public abstract T runForResult();

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

callable interface を見てください。おそらくこれはあなたのニーズに合っているでしょう。 run()メソッド内でsetter-methodを呼び出して、応答フィールドの値を取得することもできます

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

}
0
htz