[英]How to run X tasks on Y threads in Java?
I want to meassure an average time of executing a task on 5 threads doing 100 tasks. 我想确保在执行100个任务的5个线程上执行任务的平均时间。
For time meassuring purposes I use nanoTime()
为了节省时间,我使用
nanoTime()
The task is calling one specific method, let's call it foo();
任务是调用一个特定的方法,让我们称之为
foo();
I don't create any additional classes. 我不创建任何其他类。
In my code I create a task: 在我的代码中,我创建了一个任务:
Runnable thExecute = new Runnable(){
@Override
public void run(){
foo();
}
};
And then I create a thread: 然后我创建一个线程:
Thread th = new Thread(thExecute);
long start = System.nanoTime();
th.run();
long stop = System.nanoTime();
This would be great if I had the same number of tasks as threads. 如果我有与线程相同数量的任务,这将是很好的。 I tried to create arrays of threads and tasks:
我试图创建线程和任务的数组:
Runnable[] thExecutes = new Runnable[100];
Thread[] ths = new Thread[5];
But now I don't know what to do next. 但现在我不知道接下来该做什么。 I know they should be queued somehow and probably I should use
Executor
class. 我知道他们应该以某种方式排队,可能我应该使用
Executor
类。 I use Java 6. 我使用Java 6。
Edit: At first I didn't mean what I wrote. 编辑:起初我并不是说我写的东西。 Now I know I want average time + highest time.
现在我知道我想要平均时间+最长时间。
First thing to note: you should not expect precise results, if you measure performance by yourself. 首先要注意的是:如果您自己测量性能,则不应该期望精确的结果。 There are tools that do it for you, providing much more reliable results.
有一些工具可以帮到您,提供更可靠的结果。
If you want to do it by yourself, use ExecutorService: 如果您想自己动手,请使用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;
And again: since you are measuring nanoseconds, I strongly encourage you to avoid manual measurements, because there are many factors that will spoil the results: no warmup, setup expenses, etc. 再说一遍:由于你测量纳秒,我强烈建议你避免手动测量,因为有许多因素会破坏结果:没有预热,设置费用等。
Update : to measure execution time of every task, you can submit Callable<Long>
instead of Runnable
更新 :要测量每个任务的执行时间,您可以提交
Callable<Long>
而不是Runnable
public long call() {
long startTs = System.nanoTime();
// do the task
return System.nanoTime() - startTs;
}
Now Future will return the execution time, you can print it or gather in a list: 现在Future将返回执行时间,您可以打印它或收集列表:
for (Future<Long> f : futures) {
long spentTime = f.get();
}
You can use an Executor : 您可以使用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();
It will create an executor with a fix size of 5 threads then push 100 task to teh executor. 它将创建一个具有5个线程的修复大小的执行程序,然后将100个任务推送到执行程序。 The executor will dispatch the task on each thread.
执行程序将在每个线程上分派任务。
I always like to use ThreadPoolExecutor
我总是喜欢使用
ThreadPoolExecutor
ThreadPoolExecutor would be more effective if you have customized many or all of below parameters preferably : BlockingQueu
e Size (control unbounded queue size) , ThreadFactory
for custom thread life cycle management & RejectedExecutionHandler
to handle rejected tasks . 如果您已经自定义了以下许多或所有参数,则ThreadPoolExecutor会更有效:
BlockingQueu
e Size(控制无限制队列大小), ThreadFactory
用于自定义线程生命周期管理和RejectedExecutionHandler
来处理被拒绝的任务。
ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
Sample code: 示例代码:
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();
}
}
Your code simply does not run in a separate thread because of this 因此,您的代码不会在单独的线程中运行
th.run();
you should call start()
instead of run()
to achieve multi-thread functionality 你应该调用
start()
而不是run()
来实现多线程功能
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.