簡體   English   中英

如何在Java中的Y線程上運行X任務?

[英]How to run X tasks on Y threads in Java?

我想確保在執行100個任務的5個線程上執行任務的平均時間。

為了節省時間,我使用nanoTime()

任務是調用一個特定的方法,讓我們稱之為foo(); 我不創建任何其他類。

在我的代碼中,我創建了一個任務:

Runnable thExecute = new Runnable(){
  @Override
  public void run(){
    foo();
  }
};

然后我創建一個線程:

Thread th = new Thread(thExecute);
long start = System.nanoTime();
th.run();
long stop = System.nanoTime();

如果我有與線程相同數量的任務,這將是很好的。 我試圖創建線程和任務的數組:

Runnable[] thExecutes = new Runnable[100];
Thread[] ths = new Thread[5];

但現在我不知道接下來該做什么。 我知道他們應該以某種方式排隊,可能我應該使用Executor類。 我使用Java 6。

編輯:起初我並不是說我寫的東西。 現在我知道我想要平均時間+最長時間。

首先要注意的是:如果您自己測量性能,則不應該期望精確的結果。 有一些工具可以幫到您,提供更可靠的結果。

如果您想自己動手,請使用ExecutorService:

ExecutorService service = Executors.newFixedThreadPool(5);
long startTs = System.nanoTime();

List<Future> futures = new ArrayList<>();
for (Runnable r : runnables) {
    futures.add(service.submit(r));
}
for (Future f : futures) { 
    f.get(); 
}

long durationNs = System.nanoTime() - startTs;

再說一遍:由於你測量納秒,我強烈建議你避免手動測量,因為有許多因素會破壞結果:沒有預熱,設置費用等。

更新 :要測量每個任務的執行時間,您可以提交Callable<Long>而不是Runnable

public long call() {
    long startTs = System.nanoTime();
    // do the task
    return System.nanoTime() - startTs;
}

現在Future將返回執行時間,您可以打印它或收集列表:

for (Future<Long> f : futures) {
    long spentTime = f.get();
}

您可以使用Executor

ExecutorService executorService = Executors.newFixedThreadPool(5);
long start = System.nanoTime();
for (int i = 0; i < 100; i++) {
    executorService.submit(new Runnable() {

        @Override
        public void run() {
            foo();
        }
    });
}
try {
    // set whatever timeout value you want (must be > than the execution time)
    executorService.awaitTermination(1, TimeUnit.MINUTES); 
} catch (InterruptedException e) {
    e.printStackTrace();
}
long stop = System.nanoTime();

它將創建一個具有5個線程的修復大小的執行程序,然后將100個任務推送到執行程序。 執行程序將在每個線程上分派任務。

我總是喜歡使用ThreadPoolExecutor

如果您已經自定義了以下許多或所有參數,則ThreadPoolExecutor會更有效: BlockingQueu e Size(控制無限制隊列大小), ThreadFactory用於自定義線程生命周期管理和RejectedExecutionHandler來處理被拒絕的任務。

ThreadPoolExecutor(int corePoolSize, 
               int maximumPoolSize, 
               long keepAliveTime, 
               TimeUnit unit, 
               BlockingQueue<Runnable> workQueue, 
               ThreadFactory threadFactory,
               RejectedExecutionHandler handler)

示例代碼:

import java.util.concurrent.*;

import java.util.concurrent.ThreadPoolExecutor.DiscardPolicy;

class SimpleThreadFactory implements ThreadFactory {
   String name;
   static int threadNo = 0;

   public SimpleThreadFactory (String name){
       this.name = name;
   }
   public Thread newThread(Runnable r) {
     ++threadNo;
     System.out.println("thread no:"+threadNo);
     return new Thread(r,name+":"+threadNo );
   }
   public static void main(String args[]){
        SimpleThreadFactory factory = new SimpleThreadFactory("Factory Thread");
        final ThreadPoolExecutor executor = new ThreadPoolExecutor(5,20,10,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(10),factory,new ThreadPoolExecutor.DiscardPolicy());
        for ( int i=0; i < 1000; i++){
            executor.submit(new Runnable(){
                 public void run(){
                   // Add t1 here
                    System.out.println("Thread Name in Runnable:"+Thread.currentThread().getName()+ " of "+ executor.getPoolSize() );
                   // print System.currentTimeMillies - t1 here
                 }
            });
        }
        executor.shutdown();
    }
 }

因此,您的代碼不會在單獨的線程中運行

th.run();

你應該調用start()而不是run()來實現多線程功能

暫無
暫無

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

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