web-dev-qa-db-ja.com

void戻り値型でCallableを使用するには?

複数のインターフェイスと、これら2つのインターフェイスを実装する必要がある2つの実装クラスがあるプロジェクトに取り組んでいます。

私の最初のインターフェースが-

public Interface interfaceA {
    public void abc() throws Exception;
}

そしてその実装は-

public class TestA implements interfaceA {

// abc method
}

私はこのように呼んでいます-

TestA testA = new TestA();
testA.abc();

今、私の2番目のインターフェースは-

public Interface interfaceB {
    public void xyz() throws Exception;
}

そしてその実装は-

public class TestB implements interfaceB {

// xyz method   
}

私はこのように呼んでいます-

TestB testB = new TestB();
testB.xyz();

問題ステートメント:-

今私の質問は-これらの2つの実装クラスを並行して実行する方法はありますか?順番に実行したくありません。

つまり、TestATestBの実装を並行して実行したいですか?これは可能ですか?

ここでCallableを使用することを考えていましたが、ここでvoid戻り型でCallableを使用する方法がわかりません-

TestBクラスを例として使用してみましょう。

public interface interfaceB {
    public void xyz() throws Exception;
}

public class TestB implements interfaceB, Callable<?>{

    @Override
    public void xyz() throws Exception
    {
        //do something

    }

    @Override
    public void call() throws Exception
    {
        xyz();
    }
}

上記のコードはコンパイルエラーを示します。

更新:-

多くの人がcallableではなくRunnableを使用することを提案しているようです。しかし、TestA and TestBを並行して実行できるように、ここでRunnableをどのように使用すればよいかわかりません。

55
AKIWEB

Java.lang.Threadを並列実行に使用できます。ただし、ほとんどの場合、Java.util.concurrent.ExecutorServiceを使用する方が簡単です。後者はCallableを送信し、後で結果を取得する(または完了を待つ)ためにFutureを返すメソッドを提供します。

testA.abc()testB.xyz()を並行して実行する必要がある場合は、ExecutorServiceを使用して前者を個別に実行します一方、後者は元のスレッドで実行されます。次に、同期の前者の完了を待ちます。

ExecutorService executor = ... // e.g. Executors.newFixedThreadPool(4);

Future<Void> future = executor.submit(new Callable<Void>() {
    public Void call() throws Exception {
        testA.abc();
        return null;
    }
});
testB.xyz();
future.get(); // wait for completion of testA.abc()
73
nosid

なぜ並列で何かを実行するためにvoidが必要なのですか?たとえば、戻り値が必要ない場合は、単にnullを返すことができます。

何かを並行させるには、スレッド化/スケジューリングを使用する必要があります。個人的にCallablesを避け、代わりにRunnablesを使用することをお勧めします(そして、ちょっと、戻り値はありません)。

5
Rogue

短いバージョン:

ExecutorService executor = ... // e.g. Executors.newFixedThreadPool(4);
Future<?> future = executor.submit(() -> testA.abc());
testB.xyz();
future.get(); // wait for completion of testA.abc()

返されるものと並行して何かを実行しなければならないことは、悪いパターンの兆候である可能性があることに注意してください:)

また、Spring環境にいる場合は、次を使用できます。 https://spring.io/guides/gs/async-method/

1
AddJ