Index: src/com/github/rjeschke/neetutils/dispose/Disposer.java |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/src/com/github/rjeschke/neetutils/dispose/Disposer.java |
@@ -0,0 +1,99 @@ |
+/* |
+ * Copyright (C) 2012 René Jeschke <rene_jeschke@yahoo.de> |
+ * |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
+ * you may not use this file except in compliance with the License. |
+ * You may obtain a copy of the License at |
+ * |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
+ * |
+ * Unless required by applicable law or agreed to in writing, software |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+ * See the License for the specific language governing permissions and |
+ * limitations under the License. |
+ */ |
+package com.github.rjeschke.neetutils.dispose; |
+ |
+import java.lang.ref.ReferenceQueue; |
+import java.lang.ref.WeakReference; |
+ |
+import com.github.rjeschke.neetutils.dispose.ReferenceList.Node; |
+ |
+/** |
+ * |
+ * @author René Jeschke (rene_jeschke@yahoo.de) |
+ * |
+ */ |
+public class Disposer extends WeakReference<Disposable> |
+{ |
+ private final Disposable disposable; |
+ private final Node<Disposer> disposer; |
+ private volatile boolean disposed = false; |
+ final static ReferenceQueue<Disposable> refQueue; |
+ final static ReferenceList<Disposer> disposers; |
+ |
+ static |
+ { |
+ refQueue = new ReferenceQueue<Disposable>(); |
+ disposers = new ReferenceList<Disposer>(); |
+ |
+ final Thread thread = new Thread(new Cleaner()); |
+ thread.setName("neetutils-Disposer"); |
+ thread.setDaemon(true); |
+ thread.start(); |
+ } |
+ |
+ public Disposer(final Disposable referent, final Disposable disposable) |
+ { |
+ super(referent, refQueue); |
+ this.disposable = disposable; |
+ synchronized (disposers) |
+ { |
+ this.disposer = disposers.add(this); |
+ } |
+ } |
+ |
+ public void dispose() |
+ { |
+ if (!this.disposed) |
+ { |
+ synchronized (disposers) |
+ { |
+ disposers.remove(this.disposer); |
+ } |
+ this.disposed = true; |
+ this.disposable.dispose(); |
+ } |
+ } |
+ |
+ public boolean isDisposed() |
+ { |
+ return this.disposed; |
+ } |
+ |
+ private static final class Cleaner implements Runnable |
+ { |
+ public Cleaner() |
+ { |
+ // empty |
+ } |
+ |
+ @Override |
+ public void run() |
+ { |
+ final ReferenceQueue<Disposable> refQueue = Disposer.refQueue; |
+ for (;;) |
+ { |
+ try |
+ { |
+ ((Disposer)refQueue.remove()).dispose(); |
+ } |
+ catch (final Throwable t) |
+ { |
+ // |
+ } |
+ } |
+ } |
+ } |
+} |