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
変数にアクセスしたいのですが、これは可能ですか?
つかいます 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も実装する必要があります。
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 クラスをご覧ください。通常、これは executorサービス を介して送信されます
スレッドが完了すると返される将来のオブジェクトを返すことができます
はい、回避策があります。キューを使用して、返りたい値を入れてください。そして、この値を別のスレッドから取得します。
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の有用な行のみ) 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
を使用して、スレッドからの値を保持できます。
以下をお試しください
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);
}