首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

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

2012-12-20 
Future机制用于并发编程时的死锁检测Netty源码里面有个类:DeadLockProofWorker,源码如下:? public static

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

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,然后抛出异常避免死锁。

?

?

热点排行