且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

java - DelayQueue中take方法的相关疑问(内存泄漏)

更新时间:2023-09-29 16:45:28

自问自答

缺失的知识点是:

Condition.await()会自行释放锁。

参考资料

https://segmentfault.com/q/1010000002390706
http://***.com/questions/27058828/why-await-of-condition-releases-the-lock-but-signal-does-not

以下摘取部分内容

jdk1.8 await方法的说明

The lock associated with this Condition is atomically released and the current thread becomes disabled for thread scheduling purposes and lies dormant until one of four things happens:

  • Some other thread invokes the signal() method for this Condition and the current thread happens to be chosen as the thread to be awakened; or

  • Some other thread invokes the signalAll() method for this Condition; or

  • Some other thread interrupts the current thread, and interruption of thread suspension is supported; or

  • A "spurious wakeup" occurs.

In all cases, before this method can return the current thread must re-acquire the lock associated with this condition. When the thread returns it is guaranteed to hold this lock.

评论

the API would become confusing: there would be more than one method releasing the lock

自行的测试代码

public class ConditionReleaseTest {

public static void main(String[] args) {

    ReentrantLock lock = new ReentrantLock();

    final Condition con1 = lock.newCondition();

    Thread thread1 = new Thread(new Runnable() {
        @Override
        public void run() {

            lock.lock();
            try {
                System.out.println("线程1获取锁,condition wait 10s");
                con1.await(10, TimeUnit.SECONDS);
                System.out.println("线程1获取锁,condition wait 10s 结束 假定拥有锁?");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                System.out.println("线程1释放锁");
                lock.unlock();

            }
        }
    });

    Thread thread2 = new Thread(new Runnable() {
        @Override
        public void run() {

            lock.lock();
            try {
                Thread.sleep(100L);
                System.out.println("线程2 获得锁 睡眠20秒 拥有锁");
                Thread.sleep(20000L);
            } catch (Exception e) {
            } finally {
                System.out.println("线程2释放锁");
                lock.unlock();
            }
        }
    });
    thread1.start();
    thread2.start();
}
}

运行结果:

线程1获取锁,condition wait 10s
线程2 获得锁 睡眠20秒 拥有锁
线程2释放锁
线程1获取锁,condition wait 10s 结束 假定拥有锁?
线程1释放锁

在有以上知识点的基础上,我所有的疑问都可以解释的通了。

first变量会引起内存泄漏

感谢所有回答的人。

@iMouseWu @kevinz @scort

ps: peek()只是查询第一个元素,不会从队列里取出。