- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个可启动线程的可调用对象(该线程运行一个 ping 进程),我想允许用户取消任务:
public class PingCallable implements Callable<PingResult> {
private ProcThread processThread;
public PingCallable(String ip) {
this.processThread = new ProcThread(ip);
}
@Override
public PingResult call() throws Exception {
log.trace("Checking if the ip " + ip + " is alive");
try {
processThread.start();
try {
processThread.join();
} catch (InterruptedException e) {
log.error("The callable thread was interrupted for " + processThread.getName());
processThread.interrupt();
// Good practice to reset the interrupt flag.
Thread.currentThread().interrupt();
}
} catch (Throwable e) {
System.out.println("Throwable ");
}
return new PingResult(ip, processThread.isPingAlive());
}
}
ProcThread,看起来像:
@Override
public void run() {
try {
process = Runtime.getRuntime().exec("the long ping", null, workDirFile);
/* Get process input and error stream, not here to keep it short*/
// waitFor is InterruptedException sensitive
exitVal = process.waitFor();
} catch (InterruptedException ex) {
log.error("interrupted " + getName(), ex);
process.destroy();
/* Stop the intput and error stream handlers, not here */
// Reset the status, good practice
Thread.currentThread().interrupt();
} catch (IOException ex) {
log.error("Exception while execution", ex);
}
}
测试:
@Test
public void test() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(15);
List<Future<PingResult>> futures = new ArrayList<>();
for (int i= 0; i < 100; i++) {
PingCallable pingTask = new PingCallable("10.1.1.142");
futures.add(executorService.submit(pingTask));
}
Thread.sleep(10000);
executorService.shutdownNow();
// for (Future<PingResult> future : futures) {
// future.cancel(true);
// }
}
我使用ProcessExplorer监控ping进程,我看到15,然后执行shutdownNow,或者future.cancel(true),只有4-5个最多8个进程被中断,其余的都活着,我几乎从来没有看到15消息显示“可调用线程被中断..”,并且测试直到进程结束才完成。 这是为什么?
最佳答案
我可能没有完整的答案,但有两件事需要注意:
shutdownNow
发出关闭信号,要查看线程是否实际停止,请使用 awaitTermination
process.destroy()
执行也需要时间,因此可调用程序应该在中断进程线程后等待其完成。我稍微修改了一下代码,发现future.cancel(true)
实际上会阻止 catch InterruptedException
中任何内容的执行-ProcThread block ,除非您使用 executor.shutdown()
而不是executor.shutdownNow()
。当打印“Executor终止:true”时,单元测试完成(使用junit 4.11)。看起来像使用 future.cancel(true)
和executor.shutdownNow()
将双重中断线程,这可能导致中断 block 被跳过。
下面是我用于测试的代码。取消注释 for (Future<PingResult> f : futures) f.cancel(true);
与 shutdown(Now)
一起查看输出的差异。
public class TestRunInterrupt {
static long sleepTime = 1000L;
static long killTime = 2000L;
@Test
public void testInterrupts() throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(3);
List<Future<PingResult>> futures = new ArrayList<Future<PingResult>>();
for (int i= 0; i < 100; i++) {
PingCallable pingTask = new PingCallable("10.1.1.142");
futures.add(executorService.submit(pingTask));
}
Thread.sleep(sleepTime + sleepTime / 2);
// for (Future<PingResult> f : futures) f.cancel(true);
// executorService.shutdown();
executorService.shutdownNow();
int i = 0;
while (!executorService.isTerminated()) {
System.out.println("Awaiting executor termination " + i);
executorService.awaitTermination(1000L, TimeUnit.MILLISECONDS);
i++;
if (i > 5) {
break;
}
}
System.out.println("Executor terminated: " + executorService.isTerminated());
}
static class ProcThread extends Thread {
static AtomicInteger tcount = new AtomicInteger();
int id;
volatile boolean slept;
public ProcThread() {
super();
id = tcount.incrementAndGet();
}
@Override
public void run() {
try {
Thread.sleep(sleepTime);
slept = true;
} catch (InterruptedException ie) {
// Catching an interrupted-exception clears the interrupted flag.
System.out.println(id + " procThread interrupted");
try {
Thread.sleep(killTime);
System.out.println(id + " procThread kill time finished");
} catch (InterruptedException ie2) {
System.out.println(id + "procThread killing interrupted");
}
Thread.currentThread().interrupt();
} catch (Throwable t) {
System.out.println(id + " procThread stopped: " + t);
}
}
}
static class PingCallable implements Callable<PingResult> {
ProcThread pthread;
public PingCallable(String s) {
pthread = new ProcThread();
}
@Override
public PingResult call() throws Exception {
System.out.println(pthread.id + " starting sleep");
pthread.start();
try {
System.out.println(pthread.id + " awaiting sleep");
pthread.join();
} catch (InterruptedException ie) {
System.out.println(pthread.id + " callable interrupted");
pthread.interrupt();
// wait for kill process to finish
pthread.join();
System.out.println(pthread.id + " callable interrupt done");
Thread.currentThread().interrupt();
} catch (Throwable t) {
System.out.println(pthread.id + " callable stopped: " + t);
}
return new PingResult(pthread.id, pthread.slept);
}
}
static class PingResult {
int id;
boolean slept;
public PingResult(int id, boolean slept) {
this.id = id;
this.slept = slept;
System.out.println(id + " slept " + slept);
}
}
}
没有 future.cancel(true)
的输出或与 future.cancel(true)
和正常shutdown()
:
1 starting sleep
1 awaiting sleep
2 starting sleep
3 starting sleep
2 awaiting sleep
3 awaiting sleep
1 slept true
3 slept true
2 slept true
5 starting sleep
4 starting sleep
6 starting sleep
5 awaiting sleep
6 awaiting sleep
4 awaiting sleep
4 callable interrupted
Awaiting executor termination 0
6 callable interrupted
4 procThread interrupted
5 callable interrupted
6 procThread interrupted
5 procThread interrupted
Awaiting executor termination 1
6 procThread kill time finished
5 procThread kill time finished
4 procThread kill time finished
5 callable interrupt done
5 slept false
6 callable interrupt done
4 callable interrupt done
6 slept false
4 slept false
Executor terminated: true
输出为 future.cancel(true)
和shutdownNow()
:
1 starting sleep
2 starting sleep
1 awaiting sleep
2 awaiting sleep
3 starting sleep
3 awaiting sleep
3 slept true
2 slept true
1 slept true
4 starting sleep
6 starting sleep
5 starting sleep
4 awaiting sleep
5 awaiting sleep
6 awaiting sleep
5 callable interrupted
6 callable interrupted
4 callable interrupted
5 procThread interrupted
6 procThread interrupted
4 procThread interrupted
Executor terminated: true
关于java - 从 Callable 启动和停止 Process Thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26505170/
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 8 年前。 Improve th
我想知道如果我们有一个引用 const 的函数参数会发生什么功能如下图。 版本 1 int anotherFunc() { std::cout<<"inside anotherFunc"<
我正在尝试运行YOLOv8重新训练的对象检测测试,但我一直收到此错误。。我已经试过安装gnu-cobol和更新西芹了,还有其他想法吗?谢谢
我做了一个静态类方法(这里称为“函数”)f需要一个列表 Callable小号: import java.util.concurrent.*; import java.util.*; class A {
以下是我的类定义: class logline: def __init__(self,t,cmp,msg): self.t = t self.cmp = cmp
我正在用 dart 做一个小实验,我找不到一种方法来确定一个变量是否是“可调用的”,而无需显式检查每种类型(字符串、整数、 bool 等),并猜测它是否是可调用的,如果没有的话那些。我还尝试了一个 t
我大量使用来自 python 3 的 python 类型支持。 最近我试图将一个函数作为参数传递,但我没有找到使用 kwargs 的任何帮助。在 typing.Callable签名。 请检查下面的代码
每当我运行实现可调用的程序时,我都会以顺序形式获得输出。 就像,这是我的程序: package com.handson; import java.util.concurrent.ArrayBlocki
我编写了一个注释(在Spring Boot应用程序中)并尝试将其应用到Callable的call()方法上,但它不起作用,但另一方面,当应用于普通方法时(请参阅下面的代码),它有效,这一直困扰着我,你
我试图将对象列表拆分为较小的子列表,并在不同的线程上单独处理它们。所以我有以下代码: List instances = xmlInstance.readInstancesFromXml
我想我可以用 std.traits.functionAttributes 来做到这一点,但它不支持 static。对于任何类型的可调用对象(包含 opCall 的结构),我如何判断该可调用对象是否使用
我是新来的,如果我把这个放到错误的主题中,很抱歉? 我的问题: class TaskEol implements Callable> { ArrayList coordinates =
我有一些代码可以从目录中的多个 JAR 动态加载类。因为 JAR 中的代码是不受信任的,所以我希望通过对它们进行“沙盒处理”来保护主应用程序免受编码不良或恶意动态类的影响。我想做的一件事是“时间盒”不
这个问题在这里已经有了答案: Overriding special methods on an instance (5 个答案) 关闭 9 年前。 我有以下代码 import numpy as np
我正在尝试制作一个类似于 https://github.com/ElgarL/TownyChat/blob/master/src/com/palmergames/bukkit/TownyChat/To
有人可以解释为什么要继承未参数化和参数化的Callable: from typing import Callable from typing import NoReturn from typing i
我有一个任务要以固定速率运行。但是,我还需要每次执行后的任务结果。这是我尝试过的: 任务 class ScheduledWork implements Callable { public St
给定一个实例 x的 Callable , 我怎样才能运行 x在一个单独的进程中,以便我可以重定向进程的标准输入和输出?例如,有没有办法构建一个 Process来自Callable ?有没有标准Exec
我有以下可调用对象: public class Worker implements Callable{ @Override public Boolean call(){ boo
现在很清楚了what a metaclass is ,有一个相关的概念,我一直在使用,但不知道它的真正含义。 我想每个人都犯了一次括号错误,导致“对象不可调用”异常。更何况,使用 __init__ 和
我是一名优秀的程序员,十分优秀!