- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我有一个关于 ExecutorService
如何在 Java 中工作的基本问题。
很难看出简单地创建 Threads
以并行执行某些任务和将每个任务分配给 ThreadPool
之间的区别。
ExecutorService
看起来也非常简单高效,所以我想知道为什么我们不一直使用它。
这只是一种方式比另一种更快地执行其工作的问题吗?
这里有两个非常简单的例子来说明这两种方式之间的区别:
使用执行器服务: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 接口(interface),你能告诉我两者之间的区别,在什么情况下应该使用特定的而不是另一个?
使用执行器服务:计数器(任务)
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 不会在突然发生时崩溃峰)。
By Vince Emigh:
ExecutorService
also supportscachedThreadPool
, which doesn't have a max. The main reason people choose to useExecutorService
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 aboutsingleThreadExecutor
.
现在,关于 Runnable
与 Callable
的话题,从您的示例中很容易看出。 Callable
s 可以返回一个值占位符 (Future
),该占位符最终将在未来由实际值填充。 Runnable
s 不能返回任何东西。
By Vince Emigh:
Runnable
also cannot throw exceptions, whileCallable
can.
关于java - ExecutorService vs Casual Thread Spawner,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26938210/
我需要生成一个密码: 最小长度:7 最大长度:15 大写:至少一个字母 小写:至少一个字母 特殊字符 ~ ! @# $ % ^ * ( ) _ + ? 我使用了临时库,但无法生成特殊字符。谁能帮我解决
我有一个关于 ExecutorService 如何在 Java 中工作的基本问题。 很难看出简单地创建 Threads 以并行执行某些任务和将每个任务分配给 ThreadPool 之间的区别。 Exe
我开始遭受 MySQL 服务器奇怪的无法完成“临时”更新/删除查询的困扰。我对“随意”的定义是普通的查询,并且一直在发生,突然间其中一个查询就卡住了并且永远不会完成。在此期间,服务器磁盘 I/O 很高
概括地说,有一个时间序列数据集(假设1000个样本),我取100个第一个样本(0到99),得到小波并重建它(或等效地,去噪它),然后将窗口移动1(1到100),再做一次,就像移动均值算法一样。但有一个
我是一名优秀的程序员,十分优秀!