< prev index next >

src/java.base/share/classes/java/lang/ref/ReferenceQueue.java

Print this page

  1 /*
  2  * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any

128             timeout -= (end - start) / 1000_000;
129             if (timeout <= 0) return null;
130             start = end;
131         }
132     }
133 
134     private Reference<? extends T> remove0() throws InterruptedException { // must hold lock
135         for (;;) {
136             var r = poll0();
137             if (r != null) return r;
138             lock.wait();
139         }
140     }
141 
142     boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
143         synchronized (lock) {
144             return enqueue0(r);
145         }
146     }
147 
148     private boolean tryDisablePreempt() {
149         if (Thread.currentThread().isVirtual() && ContinuationSupport.isSupported()) {
150             Continuation.pin();
151             return true;
152         } else {
153             return false;
154         }
155     }
156 
157     private void enablePreempt() {
158         Continuation.unpin();
159     }
160 
161     /**
162      * Polls this queue to see if a reference object is available.  If one is
163      * available without further delay then it is removed from the queue and
164      * returned.  Otherwise this method immediately returns {@code null}.
165      *
166      * @return  A reference object, if one was immediately available,
167      *          otherwise {@code null}
168      * @see java.lang.ref.Reference#enqueue()
169      */
170     public Reference<? extends T> poll() {
171         if (head == null)
172             return null;
173 
174         // Prevent a virtual thread from being preempted as this could potentially
175         // deadlock with a carrier that is polling the same reference queue.
176         boolean disabled = tryDisablePreempt();
177         try {
178             synchronized (lock) {
179                 return poll0();
180             }
181         } finally {
182             if (disabled) enablePreempt();
183         }
184     }
185 
186     /**
187      * Removes the next reference object in this queue, blocking until either
188      * one becomes available or the given timeout period expires.
189      *
190      * <p> This method does not offer real-time guarantees: It schedules the
191      * timeout as if by invoking the {@link Object#wait(long)} method.
192      *
193      * @param  timeout  If positive, block for up to {@code timeout}
194      *                  milliseconds while waiting for a reference to be
195      *                  added to this queue.  If zero, block indefinitely.
196      *
197      * @return  A reference object, if one was available within the specified
198      *          timeout period, otherwise {@code null}
199      *
200      * @throws  IllegalArgumentException
201      *          If the value of the timeout argument is negative
202      *

  1 /*
  2  * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any

128             timeout -= (end - start) / 1000_000;
129             if (timeout <= 0) return null;
130             start = end;
131         }
132     }
133 
134     private Reference<? extends T> remove0() throws InterruptedException { // must hold lock
135         for (;;) {
136             var r = poll0();
137             if (r != null) return r;
138             lock.wait();
139         }
140     }
141 
142     boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
143         synchronized (lock) {
144             return enqueue0(r);
145         }
146     }
147 













148     /**
149      * Polls this queue to see if a reference object is available.  If one is
150      * available without further delay then it is removed from the queue and
151      * returned.  Otherwise this method immediately returns {@code null}.
152      *
153      * @return  A reference object, if one was immediately available,
154      *          otherwise {@code null}
155      * @see java.lang.ref.Reference#enqueue()
156      */
157     public Reference<? extends T> poll() {
158         if (head == null)
159             return null;
160 
161         // Prevent a virtual thread from being preempted as this could potentially
162         // deadlock with a carrier that is polling the same reference queue.
163         boolean pinned = Thread.currentThread().isVirtual() && ContinuationSupport.pinIfSupported();
164         try {
165             synchronized (lock) {
166                 return poll0();
167             }
168         } finally {
169             if (pinned) Continuation.unpin();
170         }
171     }
172 
173     /**
174      * Removes the next reference object in this queue, blocking until either
175      * one becomes available or the given timeout period expires.
176      *
177      * <p> This method does not offer real-time guarantees: It schedules the
178      * timeout as if by invoking the {@link Object#wait(long)} method.
179      *
180      * @param  timeout  If positive, block for up to {@code timeout}
181      *                  milliseconds while waiting for a reference to be
182      *                  added to this queue.  If zero, block indefinitely.
183      *
184      * @return  A reference object, if one was available within the specified
185      *          timeout period, otherwise {@code null}
186      *
187      * @throws  IllegalArgumentException
188      *          If the value of the timeout argument is negative
189      *
< prev index next >