Javaで別のスレッドでメソッドを呼び出す方法は?


126

メソッドがあるとしましょうdoWork()。(メインスレッドではなく)別のスレッドから呼び出すにはどうすればよいですか。


この最近の関連する質問には、いくつかの例があります
。Javaの

stackoverflow.com/questions/36832094/…同様の問題があり、これを解決するのに役立ちます
Sruthi Acg

また、のような反応性のJavaを見てみることかもしれblog.danlew.net/2014/09/15/grokking-rxjava-part-1非同期タスクのために
ネイサン・ダン

回答:


138

Runnableインターフェイスを実装するクラスを作成します。実行するコードをrun()メソッドに配置しRunnableます。これは、インターフェイスに準拠するために記述する必要があるメソッドです。「メイン」スレッドで、新しいThreadクラスを作成し、コンストラクタにのインスタンスを渡してRunnable、それを呼び出しますstart()start魔法のように新しいスレッドを作成し、runその新しいスレッドでメソッドを呼び出すようにJVMに指示します。

public class MyRunnable implements Runnable {

    private int var;

    public MyRunnable(int var) {
        this.var = var;
    }

    public void run() {
        // code in the other thread, can reference "var" variable
    }
}

public class MainThreadClass {
    public static void main(String args[]) {
        MyRunnable myRunnable = new MyRunnable(10);
        Thread t = new Thread(myRunnable)
        t.start();
    }    
}

開始するには、Javaの同時実行チュートリアルご覧ください

メソッドが頻繁に呼び出される場合、これは高価な操作であるため、毎回新しいスレッドを作成する価値がない場合があります。ある種のスレッドプールを使用するのがおそらく最善でしょう。見ていFutureCallableExecutor中クラスjava.util.concurrentのパッケージを。


1
渡したい変数がある場合はどうなりますか?
Louis Rhys

8
このrun()メソッドはパラメータを取らないため、変数を渡すことはできません。コンストラクタで渡すことをお勧めします-私はそれを示すために私の答えを編集します。
Noel M

1
別のスレッドで1つのメソッドを呼び出す簡単な方法はありますか?私はnew Thread() { public void run() {myMethod();}}.start();方法を知っています、それが最短ですか?
Steven Roose、

@NoelMあなたとMANNの答えの違いを説明できますか?
Asif Mushtaq 2015年

2
MANNの答えは匿名の実装を使用しています-mine Runnableは拡張するクラスですRunnable。そして、それを行ったので、インスタンス化されたオブジェクトに状態を渡す独自のコンストラクタがあります。
Noel M

183
Thread t1 = new Thread(new Runnable() {
    @Override
    public void run() {
        // code goes here.
    }
});  
t1.start();

または

new Thread(new Runnable() {
     @Override
     public void run() {
          // code goes here.
     }
}).start();

または

new Thread(() -> {
    // code goes here.
}).start();

または

Executors.newSingleThreadExecutor().execute(new Runnable() {
    @Override
    public void run() {
        myCustomMethod();
    }
});

または

Executors.newCachedThreadPool().execute(new Runnable() {
    @Override
    public void run() {
        myCustomMethod();
    }
});

これは私がやっていることに対して完全に機能しました。オブザーバーパターンを使用して、Webサービスの実行と進行状況バーの更新を同時に行う必要がありました。
dpi

@Ashish:何が、なぜ編集されたのか説明してください。
MANN、2014年

1
@AshishAggarwal:作者の許可を得ずに誰かがそれをするとき、私には奇妙に見えます!
MANN 2014年

@MANNスレッドパラメータでrunメソッドを使用する理由を説明できますか?より良いパフォーマンスはありますか?
Asif Mushtaq 2015年

1
スレッドを明示的に終了する必要がありますか?スレッドを明示的に終了しないことにより、メモリリークが発生するリスクはありませんか?または、スレッドは終了したときに終了しrun()ますか?
theyuv

59

Java 8では、1行のコードでこれを行うことができます。

メソッドがパラメーターを取らない場合は、メソッド参照を使用できます。

new Thread(MyClass::doWork).start();

それ以外の場合は、ラムダ式でメソッドを呼び出すことができます。

new Thread(() -> doWork(someParam)).start();

申し訳ありませんが、正確には->どういう意味ですか?
カイル

1
それはラムダ式を作成するために使用される構文です。詳細については、これらのリンクを参照してください。Javaで「->」は何をしますか?、および Java™チュートリアル-ラムダ式
アーロンコーン

@aaroncohn素晴らしいもの!Javaのスレッドの代替手段を知っていますか?私はPythonの世界出身Celery task queueですが、非同期のものに使用するのはなぜですか
CESCO

Javaはスレッドを処理するためのより高いレベルの抽象化を持っていますが、おそらくAkkaのようなものを探していますか?
アーロンコーン、2015年

8

(DialogBoxesやMessageBoxesのように、スレッドセーフでないメソッド用に別個のスレッドを作成するなど)を呼び出すもう1つのより速いオプションは、Lamba式を使用することです。

  new Thread(() -> {
                      "code here"
            }).start();

3

少し前に、JDK5 executorサービスを使用して特定のプロセスをバックグラウンドで実行する単純なユーティリティクラスを作成しました。doWork()の戻り値は通常voidであるため、このユーティリティクラスを使用してバックグラウンドで実行することができます。

このユーティリティをドキュメント化したこの記事を参照してください。


6
FutureとCallableはあなたのためにこのようなことをします。
Amir Afghani 2010

はい、そうです。ここでの考え方は、非同期ラッパーの背後にあるインターフェースを抽象化することです。
raja kolluru 2010

リンクが壊れています(404)。
palacsint

3

RxJava 2.xでこれを実現するには、以下を使用できます。

Completable.fromAction(this::dowork).subscribeOn(Schedulers.io().subscribe();

subscribeOn()上のアクションを実行するには、スケジューラ方法の指定- RxJavaは、以下を含むいくつかの定義済みのスケジューラ、持っているSchedulers.io()スレッドプールがI / O操作のためのもの、と持っているSchedulers.computation()どのCPUが集中的な操作のために意図されています。


3

Java 8以上を使用している場合はrunAsync、クラスCompletableFutureのメソッドを使用できます

CompletableFuture.runAsync(() -> {...});

結果を返す必要がある場合は、supplyAsync代わりに使用してください

CompletableFuture.supplyAsync(() -> 1);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.