簡體   English   中英

如何在Java中設置以下線程?

[英]how do I set up the following thread in Java?

我有一個以下形式的帖子:

  1. 每個線程的每次執行都應該在類中運行一個函數。 該功能完全可以自行運行。 該函數返回一個值,比如說int。

  2. 執行完所有線程后,需要累計函數值。

所以,它(在偽代碼中)是這樣的:

  a = 0
  for each i between 1 to N
      spawn a thread independently and call the command v = f(i)
      when thread finishes, do safely: a = a + v
  end

在這種情況下我不確定如何使用Java。

問題不是創建線程,我知道這可以使用

new Thread() { 
   public void run() { 
     ... 
   } 
} 

問題在於積累所有答案。

謝謝你的任何信息。

我可能會這樣做:

 public class Main {
     int a = 0;
     int[] values;
     int[] results;

     public Main() {
         // Init values array

         results = new int[N];
     }

     public int doStuff() {
         LinkedList<Thread> threads = new LinkedList<Thread>();

         for (final int i : values) {
             Thread t = new Thread() {
                 public void run() {
                     accumulate(foo(i));
                 }
             };

             threads.add(t);
             t.start();
          }

          for (Thread t : threads) {
              try {
                  t.join();
              } catch (InterruptedException e) {
                  // Act accordingly, maybe ignore?
              }
          }

          return a;
     }

     synchronized void accumulate(int v) {
          // Synchronized because a += v is actually
          //    tmp = a + v;
          //    a = tmp;
          // which can cause a race condition AFAIK
          a += v;
     }
 }

使用ExecutorCompletionServiceExecutorCallable

從調用int函數的Callable開始:

public class MyCallable implements Callable<Integer> {
    private final int i;

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

    public Integer call() {
        return Integer.valueOf(myFunction(i));
    }
}

創建Executor

private final Executor executor = Executors.newFixedThreadPool(10);

10是一次執行的最大線程數。

然后將其包裝在ExecutorCompletionService並提交您的作業:

CompletionService<Integer> compService = new ExecutionCompletionService<Integer>(executor);

// Make sure to track the number of jobs you submit
int jobCount;
for (int i = 0; i < n; i++) {
    compService.submit(new MyCallable(i));
    jobCount++;
}

// Get the results
int a = 0;
for (int i = 0; i < jobCount; i++) {
    a += compService.take().get().intValue();
}

ExecutorCompletionService允許您在完成任務時從隊列中提取任務。 這與加入線程略有不同。 雖然總體結果是相同的,但如果要在線程完成時更新UI,則無法知道線程將使用連接完成的順序。 這最后for循環可能是這樣的:

for (int i = 0; i < jobCount; i++) {
    a += compService.take().get().intValue();
    updateUi(a);
}

這將在任務完成時更新UI。 使用Thread.join不一定會這樣做,因為您將按照調用連接的順序獲得結果, 而不是線程完成的順序。

通過使用執行程序,這還允許您限制在給定時間運行的同時作業的數量,這樣您就不會意外地對系統進行線程炸彈。

暫無
暫無

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

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