如何在Java中的Y线程上运行X任务?

时间:2016-01-20 13:04:09

标签: java multithreading executorservice multitasking threadpoolexecutor

我想确保在执行100个任务的5个线程上执行任务的平均时间。

为了节省时间,我使用return View(objectlist );

任务是调用一个特定方法,让我们称之为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]; 类。我使用Java 6。

编辑: 起初我并不是说我写的东西。现在我知道我想要平均时间+最长时间。

4 个答案:

答案 0 :(得分:5)

首先要注意的是:如果您自己衡量绩效,则不应期望获得精确的结果。有tools为你做这件事,提供更可靠的结果。

如果您想自己动手,请使用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();
}

答案 1 :(得分:2)

您可以使用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个任务推送到执行程序。执行程序将在每个线程上分派任务。

答案 2 :(得分:0)

我总是喜欢使用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();
    }
 }

答案 3 :(得分:0)

由于这个

,您的代码根本不会在单独的线程中运行
th.run();

您应该调用start()而不是run()来实现多线程功能