Java 为什么ScheduledExecutorService没有';打印堆栈跟踪?
为什么在这个例子中我们看不到stacktraceJava 为什么ScheduledExecutorService没有';打印堆栈跟踪?,java,exception-handling,scheduled-tasks,Java,Exception Handling,Scheduled Tasks,为什么在这个例子中我们看不到stacktrace public class NoStackTraceTester implements Runnable { private static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); private ScheduledFuture<?> lifeCheckFuture; @O
public class NoStackTraceTester implements Runnable {
private static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
private ScheduledFuture<?> lifeCheckFuture;
@Override
public void run() {
lifeCheckFuture = startLifecheck();
}
private ScheduledFuture<?> startLifecheck()
{
Runnable lifeCheck = new Runnable()
{
@Override
public void run()
{
System.out.println("sending lifecheck ...");
throw new RuntimeException("bang!");
}
};
return scheduler.scheduleAtFixedRate(lifeCheck, 1000, 1000, TimeUnit.MILLISECONDS);
}
public static void main(String[] args) {
new NoStackTraceTester().run();
}
}
公共类NoStackTraceTester实现可运行{
private static final ScheduledExecutorService scheduler=Executors.newSingleThreadScheduledExecutor();
私人计划未来生命检查未来;
@凌驾
公开募捐{
lifeCheckFuture=StartIFecheck();
}
private ScheduledFuture StartIFecheck()
{
Runnable lifeCheck=new Runnable()
{
@凌驾
公开募捐
{
System.out.println(“发送生命检查…”);
抛出新的RuntimeException(“砰!”);
}
};
return scheduler.scheduleAtFixedRate(lifeCheck,10001000,TimeUnit.ms);
}
公共静态void main(字符串[]args){
新建NoStatackTraceTester().run();
}
}
如果您试图对异常进行注释,您将看到lifecheck函数的重复任务。
但如果抛出异常,线程将停止,但不显示任何细节:(
你知道为什么吗?如果你想要一个异常报告,你必须自己插入处理代码。ExecutorService不会自动将异常跟踪发送到标准输出,这很好,因为这很少是我们在生产代码中需要的 基本上,这是一种方法:
public void run()
{
try {
System.out.println("sending lifecheck ...");
throw new RuntimeException("bang!");
} catch (Throwable t) { t.printStackTrace(); }
}
ExecutorService将任何捕获的Throwable放在未来对象中。如果检查此项,您可以看到引发了什么异常。这并不总是可取的,因此您可能必须在run()方法中捕获、处理或记录任何异常 注意:一旦发生异常,该任务将不再重复
Runnable lifeCheck = new Runnable() {
@Override
public void run() {
try {
System.out.println("sending lifecheck ...");
throw new RuntimeException("bang!");
} catch(Throwable t) {
// handle or log Throwable
}
}
};
可以重写ThreadPoolExecutor中的afterExecute()方法:
class MyThreadPoolExecutor extends ThreadPoolExecutor {
public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
public void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
// If submit() method is called instead of execute()
if (t == null && r instanceof Future<?>) {
try {
Object result = ((Future<?>) r).get();
} catch (CancellationException e) {
t = e;
} catch (ExecutionException e) {
t = e.getCause();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
if (t != null) {
// Exception occurred
System.err.println("Uncaught exception is detected! " + t
+ " st: " + Arrays.toString(t.getStackTrace()));
}
// ... Perform cleanup actions
}
}
final class MyTask implements Runnable {
@Override public void run() {
System.out.println("My task is started running...");
// ...
throw new ArithmeticException(); // uncatched exception
// ...
}
}
public class ThreadPoolExecutorHandler {
public static void main(String[] args) {
// Create a fixed thread pool executor
ExecutorService threadPool = new MyThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>());
threadPool.execute(new MyTask());
// ...
}
}
类MyThreadPoolExecutor扩展了ThreadPoolExecutor{
公共MyThreadPoolExecutor(int corePoolSize、int maximumPoolSize、long keepAliveTime、,
时间单位,阻塞队列(工作队列){
super(corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue);
}
@凌驾
执行后公共无效(可运行r、可丢弃t){
super.afterExecute(r,t);
//如果调用了submit()方法而不是execute()方法
if(t==null&&r未来实例){
试一试{
对象结果=((未来)r.get();
}捕获(取消异常e){
t=e;
}捕获(执行例外){
t=e.getCause();
}捕捉(中断异常e){
Thread.currentThread().interrupt();
}
}
如果(t!=null){
//发生异常
System.err.println(“检测到未捕获的异常!”+t
+“st:+Arrays.toString(t.getStackTrace());
}
//…执行清理操作
}
}
最后一个类MyTask实现Runnable{
@重写公共无效运行(){
System.out.println(“我的任务已开始运行…”);
// ...
抛出新的算术异常();//未修补的异常
// ...
}
}
公共类ThreadPoolExecutorHandler{
公共静态void main(字符串[]args){
//创建固定线程池执行器
ExecutorService threadPool=新的MyThreadPoolExecutor(10,10,0L,TimeUnit.ms,
新建LinkedBlockingQueue());
execute(newmytask());
// ...
}
}
来源:(请注意,我修改了此处发布的代码,使其不会重新执行,因为该问题只要求stacktrace打印)这是否仅在计划执行者服务中发生?您是否尝试将任务提交给单线程执行者?