美文网首页
在线程池中寻找堆栈

在线程池中寻找堆栈

作者: 即墨灯火 | 来源:发表于2019-01-02 02:15 被阅读2次

如果在提交给线程池的任务中抛出了异常,这个异常可能不会打印任何内容,也没有被任何人捕获,形成一个幽灵异常。

为了避免这种危险情况的发生,有以下解决方式

  1. 使用Future与Callable
  2. 对于Runnable,使用execute方法而非submit方法

以上两种方式可以获得异常在哪里抛出,但是仍然丢失了一个重要信息:任务的具体提交位置。

如果想进一步获取上述信息,需要自行扩展ThreadPoolExecutor,使其在调度任务之前,先保存一下提交任务线程的堆栈信息。

扩展:

execute与submit的异同

execute是Executors的接口,submit则是ExecutorService的接口
对于ThreadPoolExecutor而言,其实现了execute,而sumit方法则继承自抽象类AbstractExecutorService

对于submit方法

public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask); //AbstractExecutorService未实现execute
    return ftask;
}

/**
* @throws RejectedExecutionException {@inheritDoc}
 * @throws NullPointerException       {@inheritDoc}
*/
public <T> Future<T> submit(Runnable task, T result) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task, result);
    execute(ftask);
    return ftask;
}

/**
 * @throws RejectedExecutionException {@inheritDoc}
 * @throws NullPointerException       {@inheritDoc}
 */
public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
}

可以看到,submit事实上封装了一个Future。

因此,对于Runnable而言,应当直接使用execute方法,无需经由submit包装。对于希望获得返回值的Callable,则适合使用submit方法。

参考:
Java 8 源码
《实战Java高并发程序设计》
https://blog.csdn.net/hayre/article/details/53314599

相关文章

  • 在线程池中寻找堆栈

    如果在提交给线程池的任务中抛出了异常,这个异常可能不会打印任何内容,也没有被任何人捕获,形成一个幽灵异常。 为了避...

  • 在线程池中寻找堆栈

    首先看一个简单的案例,代码如下 结果如下: 本来应该有5个结果,但是却只得到了4个,这是由于当i取0时,100/0...

  • 线程数量设定的考虑

    我们已经知道了线程池中的最大线程数量应该被限制,才不会导致系统资源耗尽。这些系统资源包括了内存(堆栈)、打开的文件...

  • 线程池几个重要参数

    corePoolSize 线程池中常驻线程核心线程数 maximumPoolSize 线程池中同时容纳可执行的线程...

  • Java线程堆栈

    线程堆栈信息以及解决的问题 1、线程堆栈的信息都包含: 线程的名字,ID,线程的数量等。 线程的运行状态,锁的状态...

  • Android线程池 ThreadPoolExecutor

    一.ThreadPoolExecutor的构造方法 corePoolSize 程池中的核心线程数,也就是是线程池中...

  • xcode调试之LLDB调试

    1.常用 @import 框架UIKit等 bt 打印当前线程堆栈 bt all 打印所有线程堆栈 up 向上查看...

  • HttpClients中https设置超时无效的问题

    使用多线程https请求数据时,发现一段时间所有线程都锁住了,使用线程堆栈工具发现线程都锁住,堆栈信息如下 打了很...

  • 线程池

    线程饥饿:多任务混合在同一池中,如果出现互相影响的状况出现类似死锁的问题。 例如:在一个线程池中,开辟两个线程,执...

  • 查看JVM信息的命令

    1. jstack 获取线程堆栈信息 打印堆栈信息到标准输出 jstack PID 打印堆栈信息到标准输出,会打印...

网友评论

      本文标题:在线程池中寻找堆栈

      本文链接:https://www.haomeiwen.com/subject/kxralqtx.html