簡體   English   中英

如何從線程返回值(java)

[英]How to return value from thread (java)

我做了這樣的一個波紋管:

public class MyThread implements Runnable {
  private int temp;

  public MyThread(int temp){
     this.temp=temp;
  }

  @Override
  public void run() {
    temp+=10;
    return;
  }

  public int getTemp() {
    return temp;
  }
}

但是當我嘗試通過getTemp使用temp時我得到0

class Main {
  MyThread foo = new MyThread(10);
  Thread a = new Thread(foo);
  a.start();
  int aa = foo.getTemp();       
  System.out.println(aa);
}

我只想使用我在線程中所做的計算,將其存儲在一些變量中以備后用。

或者只是添加

...
a.start();
a.join(); // Add this
...

等待線程完成,然后再獲得結果。

您的問題是您試圖在計算結果之前獲得結果。 您應該等待線程完成后才能獲得結果。 這個答案也許不是最好的,但最簡單。 由於其他人已經使用過Executors課程,所以我不想重復他們的答案。 但是,在進入執行器以幫助您更好地理解線程之前,我會先熟悉Thread及其方法,因為從您的帖子看來,您似乎是該領域的新手。

感謝l4mpi(在meta網站上)指出了缺乏解釋的地方。

使用Callable代替Runnable ,它將返回一個Future,一旦完成就可以用來檢索該值。

如果需要,可以使用命名類而不是lambda表達式

import java.util.concurrent.*;

public class ReturnValueFromThread {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<Object> foo = executor.submit(() -> {
            return doWork();
        });

        System.out.println("We will reach this line before doWork is done.");
        System.out.println(foo.get()); // Will wait until the value is complete
        executor.shutdown();
    }

    private static double doWork() throws Exception {
        Thread.sleep(2000);
        return Math.random();
    }
}

在這種情況下,您必須使用Callable而不是Runnable(非常相似): http : //docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html

public class MyThread implements Callable<Integer> { 

    private int temp;

    public MyThread(int temp){
         this.temp=temp;
    }
    @Override
    public Integer call() {
        temp+=10;
        return temp;
    }

}


public static void main(String[] args) throws InterruptedException, ExecutionException {
           ExecutorService service =  Executors.newSingleThreadExecutor();
           MyThread myTask = new MyThread(10);
           Future<Integer> future = service.submit(myTask);
           Integer result = future.get();
           System.out.println(result);
}

您可以嘗試這些代碼。 通過使用Future,您可以在線程結束時保留返回值:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * @author mike
 * @date Sep 19, 2014
 * @description
 */
public class Calc {
    private static class MyCallable implements Callable<Integer> {
        private int temp = 0;

        public MyCallable(int temp) {
            this.temp = temp;
        }

        @Override
        public Integer call() {
            temp += 10;
            return temp;
        }
    }

    public static void main(String[] args) {
        MyCallable foo = new MyCallable(10);
        try {
            Future<Integer> result = Executors.newCachedThreadPool().submit(foo);
            System.out.println(result.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

有幾種與線程“共享”變量的方法。

代碼的問題在於,您傳遞的是一個按值傳遞的int 這意味着tempthis.temp是不同的變量。

其他答案建議使用“ Future是共享變量的一種方法。 使用Future ,可以確保在實際獲取該線程執行的結果之前線程已完成,因此可能與您更相關。

在線程之間共享變量的其他方式是線程安全的,但不能保證線程已完成執行:

  • 傳遞AtomicInteger並使用set方法設置值。
  • 使用返回Threads值的synchronized getter方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM