为什么线程10000 start()调用比10000 run()调用花费更多的时间? [英] Why is it that threads 10000 start() calls take more time than 10000 run() calls?

查看:175
本文介绍了为什么线程10000 start()调用比10000 run()调用花费更多的时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在线程上打个招呼,我使用run()调用(这只是一个普通方法调用)创建了一个简单的线程,并使用start()调用创建了一个重复的线程,该线程生成了另一个线程但是,处理start()调用所花费的时间要大于run()调用所花费的时间,这不是线程调用,为什么会这样?

I am doing a hello world on threads, i have created a simple thread with using the run() call (which it is just a normal method call) and a duplicate thread with using the start() call which spawns another thread to process, however, the time taken for the start() calls is more than that taken for the run() calls, which are not threaded calls, why is it so?

开始通话时间:00:00:08:300

Start call time taken: 00:00:08:300

    long time = System.currentTimeMillis();

    for (int i = 0; i < 100000; i++) {
        Thread thread = new Thread(new Car());
        thread.setName(Integer.toString(i));
        thread.start();
    }

    long completedIn = System.currentTimeMillis() - time;

    System.out.println(DurationFormatUtils.formatDuration(completedIn,
            "HH:mm:ss:SS"));

运行通话时间:00:00:01:366

Run call time taken: 00:00:01:366

    long time = System.currentTimeMillis();

    for (int i = 0; i < 100000; i++) {
        Thread thread = new Thread(new Car());
        thread.setName(Integer.toString(i));
        thread.run();
    }

    long completedIn = System.currentTimeMillis() - time;

    System.out.println(DurationFormatUtils.formatDuration(completedIn,
            "HH:mm:ss:SS"));

推荐答案

从评论到接受的回复:您对此有何建议?"

From comment to accepted response: "Would you have any advise on this?"

是的,不要直接使用线程.从Java 5开始,我们有了java.util.concurrent框架,该框架可以简化线程和任务管理.

Yes, do not use threads directly. Since java 5, we have the java.util.concurrent framework that allows to simplify thread and task management.

创建线程的成本很高.那甚至在线程运行您想要的任务之前,就必须创建它,这是一个非常漫长的过程.因此,我们有了线程池的概念.不必每次都想执行并发任务而创建新线程,而是创建需要的线程以使其准备就绪,并在需要时向它们发送任务.线程池作为第二个冒险.当任务完成时,线程不会被破坏,而是保持活动状态以运行下一个任务,因此线程创建成本仅在初始化时间发生一次.

Creating a thread is costly. That is even before the thread will run the task you want, it will have to be created, a really long process. For that very reason, we have the concept of thread pool. Instead of creating new threads each time you want to perform a concurrent task, you firt create the threads you'll need so they are ready, and you'll send them tasks when you need too. A thread pool as a second adventage. When the task is finished, the thread is not destroyed, but kept active to run the next task, so the thread creation cost occurs only one time, at initialization time.

那么您如何使用这些概念?

So how do you use theses concepts?

首先创建一个带有线程池的执行程序.为了简单起见,我们创建了一个具有100个线程的线程池(您要模拟100个并发调用的负载):

First create an executor with a thread pool. To stay simple we create a thread pool with 100 threads (as you want to simulate load of 100 concurrent calls):

ExecutorService pool = Executors.newFixedThreadPool(100);

然后您将提交任务:

long time = System.currentTimeMillis();
for (int i=0; i<100000; i++) {
  pool.execute(new Car());
}

重要的是,您将等待所有任务完成,然后再停止程序!!!

And important, you'll wait for all tasks to finish before stopping the program !!!

pool.shutdown(); //Do no longer accept new tasks.
pool.awaitTermination(1, TimeUnit.HOURS); //Wait for up to one hour for all tasks to finish.
long completedIn = System.currentTimeMillis() - time;
System.out.println(DurationFormatUtils.formatDuration(completedIn,
            "HH:mm:ss:SS"));

在您的线程代码中,您不必等待线程完成其工作,实际上,您可以确保线程创建时间,而不是任务运行时间.

In your thread code you didn't wait for the threads to finish their job, in fact you mesured the thread creation time, not the tasks running time.

代码做什么?

executor.execute方法在线程内执行提供的任务.在这里,它占用了100个线程之一,并让它执行任务.

The executor.execute method execute the provided task inside a thread. Here it take one of the 100 thread, and let it execute the task.

如果任务数超过100,会发生什么?

What happens if there is more than 100 tasks?

具有100个线程,您最多可以运行100个并发任务.其他任务将排队,直到一个任务完成,以便有一个线程可以执行它.这是确保您不会创建过多线程并且OutOfMemory或其他讨厌的事情不会发生的好方法.

With 100 threads, you can't run more than 100 concurrent tasks. Other tasks will be queued untill one task is finished so one thread is available to execute it. This is a good way to ensure you don't create too much thread and OutOfMemory or other nasty things don't happens.

您应该使用多少个线程?

How many thread should you use?

这取决于您要执行的任务类型.

This depend of the kind of tasks you want to execute.

如果它像一台Web服务器,则您通常受IO约束,等待数据库获取数据,然后等待网络发送响应,您的线程将大部分处于等待状态.因此,即使只有一个CPU也会从数十个甚至数百个线程中受益.而且,即使有更多的线程开始使整个应用程序变慢,它也允许处理用户请求,而不必等待或拒绝响应.

If it is like a web server, you are mostly IO bound waiting for the database to get data and then for the network to send the response, your thread will be mostly waiting. So even one CPU will benefit from dozen, even hundred of threads. And even if more thread start to slow down the whole application, it allow to process the user request instead of making it wait, or just deny to respond.

如果您的任务受CPU限制,则每个CPU核心都需要一个任务,以便最大程度地利用硬件,但又会限制上下文切换的开销.使用4核超线程CPU,您最多可以拥有8个并发线程.

If your task are CPU bound you'll want something like one task per CPU core so to maximise usage of your hardware but limit the overhead of context switches. With a 4 core hyperthreading CPU, you can go up to 8 concurrent threads.

此响应只是一个简短的介绍...您将通过查看java.util.concurrent软件包并阅读一些教程来了解更多.

This response is just a short introduction... You'll learn more by looking at java.util.concurrent package and reading some tutorials.

这篇关于为什么线程10000 start()调用比10000 run()调用花费更多的时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆