`
OpenMind
  • 浏览: 177114 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Future机制用于并发编程时的死锁检测

    博客分类:
  • java
 
阅读更多

Netty源码里面有个类:DeadLockProofWorker,源码如下:

 

 public static final ThreadLocal<Executor> PARENT = new ThreadLocal<Executor>();

    public static void start(final Executor parent, final Runnable runnable) {
        if (parent == null) {
            throw new NullPointerException("parent");
        }
        if (runnable == null) {
            throw new NullPointerException("runnable");
        }

        parent.execute(new Runnable() {
            public void run() {
                PARENT.set(parent);
                try {
                    runnable.run();
                } finally {
                    PARENT.remove();
                }
            }
        });
    }

    private DeadLockProofWorker() {
        super();
    }

 

 

假设有下面的代码:

 ChannelFuture f = AChannelHandlerContext.getChannel().write(res);  
     f.addListener(new ChannelFutureListener() {              
@Override  
public void operationComplete(ChannelFuture future) throws Exception {  
    future.await();//(1)Thread 1 waiting for itself to be done.    
 //ChannelFuture f is done only if this invoke returns.  
});  
    f.await();//(2)Thead 2 wait for f to be done. 
 

如果ChannelFuture没有死锁检测,那么这两个线程将永远处于死锁状态。

 

Thread2 等待ChannelFuture f 完成,ChannelFuture f 必须把listener的代码跑完才会完成,而listener也在等待future完成,于是死锁就造成了。

 

看如何用线程变量杜绝死锁。

上述代码: AChannelHandlerContext.getChannel().write(res) 会把写的操作放到线程池里异步进行,并且是这样放进去的:

DeadLockProofWorker.start(executor, ARunnable r).

上面的代码在r运行的线程里面可以通过DeadLockProofWorker.PARENT.get()获取到executor,即一个非null的对象,如果在f.await()里面检测一下,就可以知道await是否在r的线程里面了:

 

 

 public ChannelFuture await() throws InterruptedException {
        ...
        checkDeadLock();
        ...      
        return this;
}

 private static void checkDeadLock() {
        if (DeadLockProofWorker.PARENT.get() != null) {
            throw new IllegalStateException(
                    "await*() in I/O thread causes a dead lock or " +
                    "sudden performance drop. Use addListener() instead or " +
                    "call await*() from a different thread.");
        }
    }

 

如果DeadLockProofWorker.PARENT.get() != null 成立,那么当前线程就是启动线程1,然后抛出异常避免死锁。

 

 

分享到:
评论
1 楼 fengwei5129 2016-11-08  
感谢,最近在看netty源码一直搞不清楚是如何实现的死锁检测,但是这个例子给我的感觉类似饥饿不像死锁的感觉,不知您是如何看的?

相关推荐

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第一阶段23讲、多线程死锁分析,案例介绍.mp4 │ 高并发编程第一阶段24讲、线程间通信快速入门,使用wait和notify进行线程间的数据通信.mp4 │ 高并发编程第一阶段25讲、多Produce多Consume之间的...

    汪文君高并发编程实战视频资源全集

    │ 高并发编程第一阶段23讲、多线程死锁分析,案例介绍.mp4 │ 高并发编程第一阶段24讲、线程间通信快速入门,使用wait和notify进行线程间的数据通信.mp4 │ 高并发编程第一阶段25讲、多Produce多Consume之间的...

    Java并发编程原理与实战

    理解自旋锁,死锁与重入锁.mp4 深入理解volatile原理与使用.mp4 JDK5提供的原子类的操作以及实现原理.mp4 Lock接口认识与使用.mp4 手动实现一个可重入锁.mp4 AbstractQueuedSynchronizer(AQS)详解.mp4 使用AQS重写...

    Java并发编程实战

    Java并发编程实战 本书深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及...

    Java 并发编程原理与实战视频

    java并发编程原理实战 第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四个...

    龙果 java并发编程原理实战

    龙果 java并发编程原理实战 第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四...

    java并发编程面试题

    java并发编程 基础知识,守护线程与线程, 并行和并发有什么区别? 什么是上下文切换? 线程和进程区别 什么是线程和进程? 创建线程有哪几种方式?,如何避免线程死锁 线程的 run()和 start()有什么区别? 什么是 ...

    JAVA高质量并发详解,多线程并发深入讲解

    此外,书中还深入剖析了并发编程中的常见问题,如死锁、活锁、饥饿等,并提供了相应的解决方案和最佳实践。 本书注重理论与实践相结合,通过大量的示例代码和案例分析,帮助读者更好地理解和掌握并发编程的技巧和...

    龙果java并发编程完整视频

    第1节你真的了解并发吗? [免费观看][免费观看] 00:27:48分钟 | 第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看]...

    java并发编程

    第1节你真的了解并发吗? [免费观看][免费观看] 00:27:48分钟 | 第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看]...

    2万字Java并发编程面试题合集(含答案,建议收藏)

    2万字Java并发编程面试题合集(含答案,建议收藏) 具体如下 1、在 java 中守护线程和本地线程区别?2、线程与进程的区别?3、什么是多线程中的上下文切换?4、死锁与活锁的区别,死锁与饥饿的区别?5、Java 中用到...

    zio:ZIO —一种类型安全的可组合库,用于Scala中的异步和并发编程

    ZIO是用于异步和并发编程的零依赖Scala库。 ZIO由永不浪费或泄漏资源的高度可扩展的无阻塞光纤驱动,可让您构建可扩展的,灵活的,React灵敏的应用程序,以满足您的业务需求。 高性能。 使用Scala Future 100倍...

    实战Java高并发程序设计(第2版)PPT模板.pptx

    6java8/9/10与并发 01 6.1java8的函数式编程简介 02 6.2函数式编程基础 03 6.3一步一步走入函数式编程 04 6.5增强的future:completablefuture 05 6.6读写锁的改进:stampedlock 06 6.7原子类的增强 实战Java高并发...

    javaSE代码实例

    第16章 多线程——Java中的并发协作 343 16.1 线程的基本知识 343 16.1.1 多线程编程的意义 343 16.1.2 定义自己的线程 344 16.1.3 创建线程对象 345 16.1.4 启动线程 347 16.1.5 同时使用多个线程 ...

    java核心知识点整理.pdf

    JVM 运行时内存 ................................................................................................................................. 24 2.3.1. 新生代 ........................................

    JAVA核心知识点整理(有效)

    2.3. JVM 运行时内存 ................................................................................................................................. 24 2.3.1. 新生代 ....................................

Global site tag (gtag.js) - Google Analytics