/******************************************************************************* * Copyright 2012 Geoscience Australia * * 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 au.gov.ga.earthsci.worldwind.common.render.fastshape; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; /** * Helper class for running tasks. Contains a number of threads that accepts * runnables and their owner. Ensures that only one runnable from each owner * exists in the runnable queue. * * @author Michael de Hoog (michael.dehoog@ga.gov.au) */ public class SingleTaskRunner { private BlockingQueue<OwnerRunnable> queue = new LinkedBlockingQueue<OwnerRunnable>(); private Set<OwnerRunnable> set = Collections.synchronizedSet(new HashSet<OwnerRunnable>()); private final int THREAD_COUNT = 2; public SingleTaskRunner(String threadName) { for (int i = 0; i < THREAD_COUNT; i++) { Thread thread = new Thread(new Runnable() { @Override public void run() { while (true) { try { OwnerRunnable or = queue.take(); or.runnable.run(); set.remove(or); } catch (Throwable t) { t.printStackTrace(); } } } }); thread.setName(threadName + " " + i); thread.setDaemon(true); thread.start(); } } public synchronized boolean run(Object owner, Runnable runnable) { OwnerRunnable or = new OwnerRunnable(owner, runnable); if (!set.contains(or)) { set.add(or); queue.add(or); return true; } return false; } /** * Helper class that associates a {@link Runnable} and it's owner. */ public static class OwnerRunnable { public final Object owner; public final Runnable runnable; public OwnerRunnable(Object owner, Runnable runnable) { this.owner = owner; this.runnable = runnable; } @Override public int hashCode() { return owner.hashCode(); } @Override public boolean equals(Object obj) { if (owner.equals(obj)) { return true; } if (obj instanceof OwnerRunnable && owner.equals(((OwnerRunnable) obj).owner)) { return true; } return super.equals(obj); } } }