ExecutorService与Casual Thread Spawner [英] ExecutorService vs Casual Thread Spawner

查看:128
本文介绍了ExecutorService与Casual Thread Spawner的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基本的问题,关于 ExecutorService 如何在Java中运行。

I have a basic question about how ExecutorService works in Java.

很难看到简单地创建 Threads 之间的区别是并行执行某些任务并将每个任务分配给 ThreadPool

It is quite hard to see the difference between simply creating Threads to perform some tasks in parallel and assigning each tasks to the ThreadPool.

ExecutorService 看起来也非常简单有效,所以我想知道为什么我们不会一直使用它。

The ExecutorService also looks very simple and efficient to use, so I was wondering why we don't use it all the time.

这只是一种比其他方式更快地执行其工作的问题吗?

Is it just a matter of one way executing its job faster than the other ?

这里有两个非常简单示例显示两种方式之间的区别:

Here's two very simple examples to show the difference between the two ways :

使用执行程序服务:Hello World(任务)

static class HelloTask implements Runnable {
    String msg;

    public HelloTask(String msg) {
        this.msg = msg; 
    }
    public void run() {
        long id = Thread.currentThread().getId();
        System.out.println(msg + " from thread:" + id);
    }
}

使用执行器服务:Hello World(创建)执行者,提交)

static class HelloTask {
    public static void main(String[] args) {
        int ntasks = 1000;
        ExecutorService exs = Executors.newFixedThreadPool(4);

        for (int i=0; i<ntasks; i++) { 
            HelloTask t = new HelloTask("Hello from task " + i);    
            exs.submit(t);
        }
        exs.shutdown();
    }
}






下面是一个类似的例子,但是扩展了Callable接口,你能告诉我两者之间的区别吗?在哪种情况下,应该使用特定的一个而不是另一个?


the following shows a similar example but extending the Callable interface, could you tell me the difference between the two and in which cases one should use a specific one instead of the other ?

使用执行程序服务:计数器(任务)

static class HelloTaskRet implements Callable<Long> {
    String msg;

    public HelloTaskRet(String msg) {
        this.msg = msg; }

        public Long call() {
        long tid = Thread.currentThread().getId(); 
        System.out.println(msg + " from thread:" + tid); 
        return tid;
    } 
}

使用执行者服务:(创建,提交)

static class HelloTaskRet {
    public static void main(String[] args) {
        int ntasks = 1000;
        ExecutorService exs = Executors.newFixedThreadPool(4);

        Future<Long>[] futures = (Future<Long>[]) new Future[ntasks];

        for (int i=0; i<ntasks; i++) { 
            HelloTaskRet t = new HelloTaskRet("Hello from task " + i);
            futures[i] = exs.submit(t);
        }
        exs.shutdown();
    }
}


推荐答案

虽然问题和示例代码没有关联,我会尝试澄清两者。
ExecutorService相对于随意生成线程的优势在于它的行为可预测并避免了线程创建的开销,这在JVM上相对较大(例如,它需要为每个线程保留内存)。通过可预测性,至少对于 fixedThreadPool ,我的意思是你知道最大并发线程数,并且你知道它们何时以及如何被创建(所以你的JVM不会在突然出现高峰的情况下爆炸。)

While the question and the sample code do not correlate, I'll try clarifying both. The advantage of ExecutorService over haphazardly spawning threads is that it behaves predictably and avoids the overhead of thread creation, which is relatively big on the JVM (it needs to reserve memory for each thread, for example). By predictability, at least for the fixedThreadPool, I mean you know the maximum number of concurrent threads, and you know when and how they might get created (so your JVM won't blow up in case of sudden peaks).


作者:Vince Emigh:
ExecutorService 还支持 cachedThreadPool ,它没有
max。人们选择使用 ExecutorService 的主要原因是
防止创建多个线程的开销(通过使用 worker
threads
)。它主要用于许多小任务需要在单独的线程上执行
的情况。另外,不要忘记
singleThreadExecutor

By Vince Emigh: ExecutorService also supports cachedThreadPool, which doesn't have a max. The main reason people choose to use ExecutorService is to prevent the overhead of creating multiple threads (by using worker threads). It's mostly used in cases where many small tasks need to be executed on a separate thread. Also, don't forget about singleThreadExecutor.

现在,关于 Runnable vs Callable 的主题,很容易从你的例子中看到。 Callable s可以返回一个值占位符( Future ),最终将由实际值填充。 Runnable s无法返回任何内容。

Now, on the topic of Runnable vs Callable, it is easy to see from your examples. Callables can return a value place-holder (Future) that will eventually be populated by an actual value in the future. Runnables can not return anything.


作者:Vince Emigh:
Runnable 也不能抛出异常,而 Callable 可以。

By Vince Emigh: Runnable also cannot throw exceptions, while Callable can.

这篇关于ExecutorService与Casual Thread Spawner的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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