30

これは Java に関する一般的な質問であり、Android に関する質問ではありません。

セカンダリ スレッドのコンテキストから、メイン スレッドでコードを実行する方法を知りたいです。例えば:

new Thread(new Runnable() {
        public void run() {
            //work out pi to 1,000 DP (takes a while!)

            //print the result on the main thread
        }
    }).start();

そのようなこと-Javaでは何かを出力するためにメインスレッドにいる必要がなく、Swingにもイベントキューがあるため、私の例が少し貧弱であることを認識しています-しかし、必要になる可能性のある一般的な状況バックグラウンドスレッドのコンテキストで、メインスレッドで Runnable を実行します。

編集:比較のために-Objective-Cでそれを行う方法は次のとおりです:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0UL), ^{
    //do background thread stuff

    dispatch_async(dispatch_get_main_queue(), ^{
        //update UI
    });
});

前もって感謝します!

4

6 に答える 6

24

あなたが Android を使用している場合、ハンドラーを使用するとうまくいきますか?

new Handler(Looper.getMainLooper()).post(new Runnable () {
    @Override
    public void run () {
        ...
    }
});
于 2013-05-20T07:25:04.573 に答える
7

古い議論ですが、リクエストをメインスレッドに送信すること(反対方向ではない)の問題である場合は、先物でも行うことができます。基本的な目的は、バックグラウンドで何かを実行し、終了時に結果を取得することです。

public static void main(String[] args) throws InterruptedException, ExecutionException {
    // create the task to execute
    System.out.println("Main: Run thread");
    FutureTask<Integer> task = new FutureTask<Integer>(
            new Callable<Integer>() {

                @Override
                public Integer call() throws Exception {
                    // indicate the beginning of the thread
                    System.out.println("Thread: Start");

                    // decide a timeout between 1 and 5s
                    int timeout = 1000 + new Random().nextInt(4000);

                    // wait the timeout
                    Thread.sleep(timeout);

                    // indicate the end of the thread
                    System.out.println("Thread: Stop after " + timeout + "ms");

                    // return the result of the background execution
                    return timeout;
                }
            });
    new Thread(task).start();
    // here the thread is running in background

    // during this time we do something else
    System.out.println("Main: Start to work on other things...");
    Thread.sleep(2000);
    System.out.println("Main: I have done plenty of stuff, but now I need the result of my function!");

    // wait for the thread to finish if necessary and retrieve the result.
    Integer result = task.get();

    // now we can go ahead and use the result
    System.out.println("Main: Thread has returned " + result);
    // you can also check task.isDone() before to call task.get() to know
    // if it is finished and do somethings else if it is not the case.
}

バックグラウンドでいくつかのことを実行して結果を取得することが意図されている場合は、上記のようにいくつかのキューを設定するか、プロセスを複数の先物に分割することができます (一度にすべてを開始するか、別の先物からでも、必要に応じて新しいものを開始します)。 . 各タスクをマップまたはリストに保存し、メイン スレッドで初期化すると、必要な先物をいつでも確認し、完了時に結果を取得できます。

于 2015-01-15T01:11:11.793 に答える
4

ほとんどのイベント ドリブンが発生する「偶数ディスパッチ スレッド」を使用することをお勧めします。スイングを使用している場合:

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            Your code here.
        }
    });

または、Runnable を実装するクラスを作成し、invokeLater() に渡します。

于 2015-09-06T08:27:49.197 に答える
0

パーティーには少し遅れましたが、私のアプローチは少し違うと思います。

Affe のソリューションを少し変更する

 public static final BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();

  public static void main(String[] args) {

    Thread myThread = new Thread(

        () -> {
          String name = Thread.currentThread().getName();
          System.out.println("initial current thread " + name);

          queue.add(() -> System.out.println(Thread.currentThread().getName()));
        });

    myThread.setName("background thread");
    myThread.start();

    try {
      myThread.join();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    while (!queue.isEmpty()) {
      try {
        queue.take().run();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

出力

initial current thread background thread
main
于 2021-08-07T09:15:04.983 に答える