Author: doogie
Date: Thu Apr 1 04:50:21 2010 New Revision: 929844 URL: http://svn.apache.org/viewvc?rev=929844&view=rev Log: Helper class to poll a ReferenceQueue with a background thread. Added: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/ReferenceCleaner.java ofbiz/trunk/framework/base/src/org/ofbiz/base/util/test/ReferenceCleanerTests.java Added: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/ReferenceCleaner.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/ReferenceCleaner.java?rev=929844&view=auto ============================================================================== --- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/ReferenceCleaner.java (added) +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/ReferenceCleaner.java Thu Apr 1 04:50:21 2010 @@ -0,0 +1,89 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.ofbiz.base.util; + +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.PhantomReference; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; + +public final class ReferenceCleaner { + public static final String module = ReferenceCleaner.class.getName(); + + private static final class CleanerThread extends Thread { + private boolean keepRunning = true; + + protected CleanerThread() { + setDaemon(true); + setName("ReferenceCleaner"); + } + + protected void stopRunning() { + keepRunning = false; + } + + public void run() { + while (keepRunning) { + try { + ((Removable) QUEUE.remove()).remove(); + } catch (Throwable t) { + // ignore + } + if (interrupted()) { + stopRunning(); + cleanerThread = new CleanerThread(); + cleanerThread.start(); + } + } + } + } + private static CleanerThread cleanerThread = new CleanerThread(); + + static { + cleanerThread.start(); + } + + private ReferenceCleaner() { + } + + private static final ReferenceQueue<Object> QUEUE = new ReferenceQueue<Object>(); + + public interface Removable { + void remove() throws Exception; + } + + public abstract static class Soft<V> extends SoftReference<V> implements Removable { + public Soft(V value) { + super(value, QUEUE); + } + } + + public abstract static class Phantom<V> extends PhantomReference<V> implements Removable { + public Phantom(V value) { + super(value, QUEUE); + } + } + + public abstract static class Weak<V> extends WeakReference<V> implements Removable { + public Weak(V value) { + super(value, QUEUE); + } + } +} Added: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/test/ReferenceCleanerTests.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/test/ReferenceCleanerTests.java?rev=929844&view=auto ============================================================================== --- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/test/ReferenceCleanerTests.java (added) +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/test/ReferenceCleanerTests.java Thu Apr 1 04:50:21 2010 @@ -0,0 +1,82 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.ofbiz.base.util.test; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Exchanger; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.SynchronousQueue; + +import org.ofbiz.base.util.ReferenceCleaner; +import org.ofbiz.base.lang.SourceMonitored; +import org.ofbiz.base.test.GenericTestCaseBase; + +@SourceMonitored +public class ReferenceCleanerTests extends GenericTestCaseBase { + public ReferenceCleanerTests(String name) { + super(name); + } + + public void testReferenceCleaner() throws Exception { + assertStaticHelperClass(ReferenceCleaner.class); + final SynchronousQueue<String> queue = new SynchronousQueue<String>(); + Object obj = new Object(); + final CountDownLatch softLatch = new CountDownLatch(1); + ReferenceCleaner.Soft<Object> soft = new ReferenceCleaner.Soft<Object>(obj) { + public void remove() throws Exception { + queue.put("soft"); + Thread.currentThread().interrupt(); + } + }; + final CountDownLatch weakLatch = new CountDownLatch(1); + ReferenceCleaner.Weak<Object> weak = new ReferenceCleaner.Weak<Object>(obj) { + public void remove() throws Exception { + queue.put("weak"); + throw new RuntimeException(); + } + }; + final CountDownLatch phantomLatch = new CountDownLatch(1); + ReferenceCleaner.Phantom<Object> phantom = new ReferenceCleaner.Phantom<Object>(obj) { + public void remove() throws Exception { + queue.put("phantom"); + } + }; + HashSet<String> foundEvents = new HashSet<String>(); + useAllMemory(); + assertSame("still-soft", obj, soft.get()); + assertSame("still-weak", obj, weak.get()); + assertNull("no event", queue.poll(100, TimeUnit.MILLISECONDS)); + obj = null; + useAllMemory(); + foundEvents.add(queue.poll(100, TimeUnit.MILLISECONDS)); + foundEvents.add(queue.poll(100, TimeUnit.MILLISECONDS)); + foundEvents.add(queue.poll(100, TimeUnit.MILLISECONDS)); + useAllMemory(); + foundEvents.add(queue.poll(100, TimeUnit.MILLISECONDS)); + foundEvents.remove(null); + assertFalse("no null", foundEvents.contains(null)); + assertNull("no-soft", soft.get()); + assertNull("no-weak", weak.get()); + assertTrue("soft event", foundEvents.contains("soft")); + assertTrue("weak event", foundEvents.contains("weak")); + assertTrue("phantom event", foundEvents.contains("phantom")); + } +} |
Free forum by Nabble | Edit this page |