source: josm/trunk/src/org/openstreetmap/josm/tools/ListenableWeakReference.java@ 12268

Last change on this file since 12268 was 12192, checked in by michael2402, 7 years ago

Fix some Sonar warnings for ListenableWeakReference

File size: 2.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.tools;
3
4import java.lang.ref.Reference;
5import java.lang.ref.ReferenceQueue;
6import java.lang.ref.WeakReference;
7
8import org.openstreetmap.josm.tools.bugreport.BugReport;
9
10/**
11 * This is a special weak reference that notifies a listener when it is no longer available.
12 *
13 * A special dereferenced-thread is used for this, so make sure your code is thread-safe.
14 * @author Michael Zangl
15 * @since 12181
16 *
17 * @param <T> The weak reference
18 */
19public class ListenableWeakReference<T> extends WeakReference<T> {
20 private static final ReferenceQueue<Object> GLOBAL_QUEUE = new ReferenceQueue<>();
21 private static Thread thread;
22 private Runnable runOnDereference;
23
24 /**
25 * Create a new {@link ListenableWeakReference}
26 * @param referent The object that is referenced
27 */
28 public ListenableWeakReference(T referent) {
29 this(referent, () -> { });
30 }
31
32 /**
33 * Create a new {@link ListenableWeakReference}
34 * @param referent The object that is referenced
35 * @param runOnDereference The runnable to run when the object is no longer referenced.
36 */
37 public ListenableWeakReference(T referent, Runnable runOnDereference) {
38 super(referent, GLOBAL_QUEUE);
39 this.runOnDereference = runOnDereference;
40 ensureQueueStarted();
41 }
42
43 /**
44 * This method is called after the object is dereferenced.
45 */
46 protected void onDereference() {
47 this.runOnDereference.run();
48 }
49
50 private static synchronized void ensureQueueStarted() {
51 if (thread == null) {
52 thread = new Thread(ListenableWeakReference::clean, "Weak reference cleaner");
53 thread.start();
54 }
55 }
56
57 private static void clean() {
58 try {
59 while (true) {
60 Reference<? extends Object> ref = GLOBAL_QUEUE.remove();
61 if (ref instanceof ListenableWeakReference) {
62 ((ListenableWeakReference<?>) ref).onDereference();
63 }
64 }
65 } catch (InterruptedException e) {
66 BugReport.intercept(e).warn();
67 Thread.currentThread().interrupt();
68 }
69 }
70}
Note: See TracBrowser for help on using the repository browser.