启动多个 ExecutorService Java
Launch multiple ExecutorService Java
我想同时启动两个ExecutorService。
比如我的主要是:
MyClass.firstAsync();
MyClass.secondAsync();
并且,
public void firstAsync() {
ExecutorService service = Executors.newFixedThreadPool(4);
service.submit(new Runnable() {
public void run() {
while (true) {
System.out.println("I m running : First Async");
}
});
}
然后
public void secondAsync() {
ExecutorService service = Executors.newFixedThreadPool(4);
service.submit(new Runnable() {
public void run() {
while (true) {
System.out.println("I m running : Second Async");
}
});
}
问题是:当调用第二个 class 时,它取代了第一个。所以我有这个输出:
I m running : First Async
虽然第二个 ExecutorService 没有启动,但我有这个输出
I m running : Second Async
第二个启动时。
我也尝试将它们放在同一个服务上(在同一个 ExecutorService 上有两个 service.submit(...))但它根本不起作用
我想要的是两个输出,在"same time".
谢谢,
克莱门特
您不能指望控制线程的执行。
如果你想模拟它,让我们在你的循环中引入:
Thread.sleep(10);
这会强制当前 运行 线程休眠,并为其他线程提供执行的机会。
但不要指望编排线程的执行。
您的代码按预期工作。我假设您期望得到这样的输出:
I m running : First Async
I m running : Second Async
I m running : First Async
I m running : Second Async
但是你得到的是:
I m running : First Async
I m running : First Async
...
I m running : First Async
I m running : Second Async
I m running : Second Async
...
I m running : Second Async
I m running : First Async
...
I m running : First Async
I m running : Second Async
...
I m running : Second Async
也许您从一个线程获得了太多输出,以至于您看不到另一个线程的输出。
发生这种情况是因为两个线程竞争对同一输出流的访问权限 (System.out),并且每次一个线程获得访问权限时,它都会设法在另一个线程获得权限之前打印多行(可能数千行)流。
要对此进行测试,请在循环中添加延迟,这样每个线程都有时间一次只打印一行。
while (true) {
System.out.println("I m running : First Async");
Thread.sleep(100); // <---- and surround with try-catch
}
while (true) {
System.out.println("I m running : Second Async");
Thread.sleep(100); // <---- and surround with try-catch
}
(1) 你的代码没问题(除了下面的一些小评论),问题很简单,实际代码太快了,没有注意到并发!此外,println 通常是同步的。如果您将每个 "run()" 替换为一些打印多行的循环,您会注意到并发性。
(2) 我会考虑两个修复,不管:
(a) 你真的需要 2 个独立的线程池吗?这样做也没关系,只是从例子(b)中看不出原因,我觉得把线程池实例化为局部方法变量意义不大,应该放在可以复用的地方+ 监控 + 有时终止。显然,您可能只是为了讨论而简化了代码...
我想发表评论,但显然我需要在 Whosebug 上获得 50 的声誉才能发表评论(合理,但不幸。)。所以我将尝试回答这个问题。
ExecutorService 旨在成为实现 Executor 接口的管理对象,这意味着它可以在其中容纳一个线程池。线程池可用于托管各种 Runnable 线程对象。它们不必是同一类型。
例如,如果您有一个具有特定功能的 Runable class,您可以从 ExecutorService 持有的线程启动它,因为线程是通用的。如果您需要识别特定的线程以便稍后与它们交互,您可以在每个 Runnable 线程类型中使用一个特定的、不可变的标识符 class 字段和一个 getter 方法。或者,如果您愿意,可以在构造线程对象时存储对线程对象的引用。
或者,还可以查找 运行 threads/thread 组及其 ID。你可以在这里看到这个方法:
你的问题的答案是你不需要有两个 ExecutorServices。由于您可以以静态或动态方式调整线程池的大小,并且您的线程池可以托管异构线程对象。
希望对您有所帮助。我希望这是一个充分的答案。
这是我的最终答案。
在我的 firstAsync() 代码中,有一个从未显示在控制台中的 NullPointerException。
我和我服务的一个人花了一个多小时来解决这个问题。是我的错
你的回答都很好,我的问题很愚蠢。
谢谢,克莱门特。
我想同时启动两个ExecutorService。
比如我的主要是:
MyClass.firstAsync();
MyClass.secondAsync();
并且,
public void firstAsync() {
ExecutorService service = Executors.newFixedThreadPool(4);
service.submit(new Runnable() {
public void run() {
while (true) {
System.out.println("I m running : First Async");
}
});
}
然后
public void secondAsync() {
ExecutorService service = Executors.newFixedThreadPool(4);
service.submit(new Runnable() {
public void run() {
while (true) {
System.out.println("I m running : Second Async");
}
});
}
问题是:当调用第二个 class 时,它取代了第一个。所以我有这个输出:
I m running : First Async
虽然第二个 ExecutorService 没有启动,但我有这个输出
I m running : Second Async
第二个启动时。
我也尝试将它们放在同一个服务上(在同一个 ExecutorService 上有两个 service.submit(...))但它根本不起作用
我想要的是两个输出,在"same time".
谢谢, 克莱门特
您不能指望控制线程的执行。 如果你想模拟它,让我们在你的循环中引入:
Thread.sleep(10);
这会强制当前 运行 线程休眠,并为其他线程提供执行的机会。
但不要指望编排线程的执行。
您的代码按预期工作。我假设您期望得到这样的输出:
I m running : First Async
I m running : Second Async
I m running : First Async
I m running : Second Async
但是你得到的是:
I m running : First Async
I m running : First Async
...
I m running : First Async
I m running : Second Async
I m running : Second Async
...
I m running : Second Async
I m running : First Async
...
I m running : First Async
I m running : Second Async
...
I m running : Second Async
也许您从一个线程获得了太多输出,以至于您看不到另一个线程的输出。
发生这种情况是因为两个线程竞争对同一输出流的访问权限 (System.out),并且每次一个线程获得访问权限时,它都会设法在另一个线程获得权限之前打印多行(可能数千行)流。
要对此进行测试,请在循环中添加延迟,这样每个线程都有时间一次只打印一行。
while (true) {
System.out.println("I m running : First Async");
Thread.sleep(100); // <---- and surround with try-catch
}
while (true) {
System.out.println("I m running : Second Async");
Thread.sleep(100); // <---- and surround with try-catch
}
(1) 你的代码没问题(除了下面的一些小评论),问题很简单,实际代码太快了,没有注意到并发!此外,println 通常是同步的。如果您将每个 "run()" 替换为一些打印多行的循环,您会注意到并发性。
(2) 我会考虑两个修复,不管: (a) 你真的需要 2 个独立的线程池吗?这样做也没关系,只是从例子(b)中看不出原因,我觉得把线程池实例化为局部方法变量意义不大,应该放在可以复用的地方+ 监控 + 有时终止。显然,您可能只是为了讨论而简化了代码...
我想发表评论,但显然我需要在 Whosebug 上获得 50 的声誉才能发表评论(合理,但不幸。)。所以我将尝试回答这个问题。
ExecutorService 旨在成为实现 Executor 接口的管理对象,这意味着它可以在其中容纳一个线程池。线程池可用于托管各种 Runnable 线程对象。它们不必是同一类型。
例如,如果您有一个具有特定功能的 Runable class,您可以从 ExecutorService 持有的线程启动它,因为线程是通用的。如果您需要识别特定的线程以便稍后与它们交互,您可以在每个 Runnable 线程类型中使用一个特定的、不可变的标识符 class 字段和一个 getter 方法。或者,如果您愿意,可以在构造线程对象时存储对线程对象的引用。
或者,还可以查找 运行 threads/thread 组及其 ID。你可以在这里看到这个方法:
你的问题的答案是你不需要有两个 ExecutorServices。由于您可以以静态或动态方式调整线程池的大小,并且您的线程池可以托管异构线程对象。
希望对您有所帮助。我希望这是一个充分的答案。
这是我的最终答案。
在我的 firstAsync() 代码中,有一个从未显示在控制台中的 NullPointerException。
我和我服务的一个人花了一个多小时来解决这个问题。是我的错 你的回答都很好,我的问题很愚蠢。
谢谢,克莱门特。