【发布时间】:2009-12-25 09:03:08
【问题描述】:
好吧,标题说了算,Executors.newSingleThreadExecutor().execute(command)和new Thread(command).start();有什么区别
【问题讨论】:
标签: java multithreading
好吧,标题说了算,Executors.newSingleThreadExecutor().execute(command)和new Thread(command).start();有什么区别
【问题讨论】:
标签: java multithreading
在行为上,几乎没有。
然而,一旦你有了一个Executor 实例,你就可以向它提交多个任务,并让它们一个接一个地执行。你不能简单地使用原始的Thread 来做到这一点。
【讨论】:
一个明显的区别是,当你运行new Thread(someRunnable).start(); 时,当runnable 完成时,线程会安静地死掉。
Executor 将一直存在,直到您将其关闭。所以运行Executors.newSingleThreadExecutor().execute(command)当你认为你的应用程序或JVM可能已经完成时,Executor可能仍然在后台线程中运行。
【讨论】:
submit 完成后,我无法重新创建finalize 调用。我运行了一个简单的 main 测试,委托 TPE 永远不会被 GC 处理。
对于Executor.execute,如果在Executor 中抛出Error 或RuntimeException,它将被无声吞下,而new Thread() 会将其打印到System.err。
【讨论】:
Executor.submit而不是execute,然后在你想要处理潜在的Future时调用get错误。
可能有很多差异,但我将向您展示一个我认为非常重要的差异:
public void sendEventSingleThreadExecutor(Event e){
Executor.singleThreadExecutor().execute(()->{//send the event here})
}
现在,即使您调用 sendEventSingleThreadExecutor 方法10 次,它也将仅使用单个线程发送它们。它不会每次都创建一个新线程。这意味着事件将按顺序或同步发送! 您可以从here阅读更多内容:
现在看下面带有新线程的例子
public void sendEventThread(Event e){
Thread(//send the event here).start();
}
如果您调用 10 次,它将创建 10 个新线程。这意味着,执行将是异步!而且它可能很危险,它可以创建很多线程,具体取决于您调用 sendEventThread 函数的次数。
请注意,代码仅供演示,可能有语法错误! 如果您在这里发现任何错误的描述,我会很乐意更正。
来自here的更多信息
newSingleThreadExecutor。单线程执行器创建一个 工作线程来处理任务,如果它意外死亡则替换它。 任务保证按照顺序依次处理 任务队列强加的顺序(FIFO、LIFO、优先顺序)。[4]
[4] 单线程执行器也提供足够的内部 同步以保证任务所做的任何内存写入都是 对后续任务可见;这意味着对象可以安全地 仅限于“任务线程”,即使该线程可能被替换 不时与另一个人。
【讨论】:
我更喜欢使用ExecutorService 或ThreadPoolExecutor,即使是单个数字线程。它们提供了更大的灵活性。
查看相关 SE 问题中的 ExecutorService 和 ThreadPoolExecutor 部分:
java Fork/Join pool, ExecutorService and CountDownLatch
Java's Fork/Join vs ExecutorService - when to use which?
假设您从自己的线程而不是ExecutorService 开始。将来,如果需要支持多线程,ExecutorService 或ThreadPoolExecutor 将为您提供更好的控制和灵活性。您可以在以下这些 API 中微调所需的参数数量。
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)
【讨论】:
Executors.newSingleThreadExecutor().execute(command) 将重用之前构建的线程,它不会像 new Thread() 那样创建新线程。如果 60 秒未使用的线程被终止,它是一种包含单个线程的池,其等效为 newFixedThreadPool(1)。
【讨论】: