Java AbstractQueuedSynchronizer与自定义FutureTask的自定义同步?

时间:2013-12-10 21:26:50

标签: java synchronization mutex atomic

我正在实现自定义FutureTask(不扩展)以用于线程池,依此类推。我需要特殊功能,不能直接在FutureTask方法上扩展。为了帮助我这样做,我查看了默认实现。如果您无法访问代码,可以在此处查看默认实现:

http://pastebin.com/HTe6WT9S

如您所见,它使用AbstractQueuedSynchronizer。我的问题只是为什么?这个类是否超级优化还是主要是FIFO功能有吸引力?我最初的想法是使用FutureTask和其他低级构造实现我的自定义AtomicInteger,使用我对良好同步构造的平均知识来最佳地实现我的FutureTask,所以我可能不想要AQS较慢的功能,如果有的话。那么有AQS提供的其他功能吗?有什么好的论据支持/反对使用它?到目前为止,这是我有限的猜测:

AQS *也许是事实上的标准,因为它是你应该在一般情况下使用的(专业) *可以复制大部分代码(专业版) * FIFO功能很有趣,但它是否适合FutureTask? (中性) *也许它的功能使它比低级构造慢? (CON) AtomicInteger&其他低级构造 *可能你得到的速度最快? (PRO) *必须实施自我((次要)骗局) *无FIFO(con)

1 个答案:

答案 0 :(得分:1)

我刚回答what's AQS used for。请先阅读。

许多不同的线程可以保存FutureTask实例。例如:

    final FutureTask<Beef> killCows = new FutureTask<Beef>(
            new Callable<Beef>() {

                @Override
                public Beef call() throws Exception {
                    return new Beef();
                }
            });

    new Thread(new Runnable() {

        @Override
        public void run() {

            Beef beef = killCows.get();
            // prepare sirloin

        }
    }).start();

    new Thread(new Runnable() {

        @Override
        public void run() {

            Beef beef = killCows.get();
            // prepare rib

        }
    }).start();

调用FutureTask.get()的所有线程都将等待(阻止),直到任务完成或取消。必须有一些机制来通知和唤醒它们。所以答案是AQS。正如您所提到的,它确实构成了一个FIFO队列,队列中的每个节点都代表一个线程。任务完成后,将通知所有节点并获得逐个访问关键部分的权限。

请不要制作另一个FutureTask,但要先了解它。也许你可以覆盖那些受保护的方法,比如done()来完成你的工作。