All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.vesalainen.util.Recycler Maven / Gradle / Ivy

/*
 * Copyright (C) 2016 tkv
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.vesalainen.util;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import org.vesalainen.util.logging.JavaLogging;

/**
 * Recycler class is used to recycle Recyclable objects.
 * 

This kind of recycling is for special cases only. Implementation has to take * care that recycled object is not referenced. This kind of recycling can leed * to hard to find bugs. * @author tkv */ public final class Recycler { private static final MapList,Recyclable> mapList = new HashMapList<>(); private static final Lock lock = new ReentrantLock(); private static ArrayBlockingQueue queue; private static Runner runner = new Runner(); private static final JavaLogging log = new JavaLogging(Recycler.class); private static int Size = 1024; /** * Set size of inner queue. Default is 1024. * @param Size */ public static void setSize(int Size) { Recycler.Size = Size; } /** * Returns new or recycled uninitialized object. * @param * @param cls * @return */ public static final T get(Class cls) { return get(cls, null); } /** * Returns new or recycled initialized object. * @param * @param cls * @param initializer * @return */ public static final T get(Class cls, Consumer initializer) { T recyclable = null; lock.lock(); try { List list = mapList.get(cls); if (list != null && !list.isEmpty()) { recyclable = (T) list.remove(list.size()-1); log.debug("get recycled %s", recyclable); } } finally { lock.unlock(); } if (recyclable == null) { try { recyclable = cls.newInstance(); log.debug("create new recycled %s", recyclable); } catch (InstantiationException | IllegalAccessException ex) { throw new IllegalArgumentException(ex); } } if (initializer != null) { initializer.accept(recyclable); } return (T) recyclable; } /** * Add objects to be recycled. * @param * @param recyclables */ public static final void recycle(Collection recyclables) { recyclables.stream().forEach((recyclable) -> { recycle(recyclable); }); } /** * Add objects to be recycled. * @param * @param recyclables */ public static final void recycle(T... recyclables) { for (Recyclable recyclable : recyclables) { recycle(recyclable); } } /** * Add object to be recycled. * @param * @param recyclable */ public static final void recycle(T recyclable) { lock.lock(); try { if (queue == null) { queue = new ArrayBlockingQueue<>(Size); Thread thread = new Thread(runner, Recycler.class.getSimpleName()); thread.start(); log.info("start thread %s", Recycler.class.getSimpleName()); } if (!queue.offer(recyclable)) { log.warning("failed to recycle %s, queue is full", recyclable); } else { log.debug("put to recycle queue %s", recyclable); } } finally { lock.unlock(); } } static final boolean isRecycled(T recyclable) { return mapList.contains(recyclable.getClass(), recyclable); } private static class Runner implements Runnable { @Override public void run() { while (true) { try { Recyclable recyclable = queue.poll(1, TimeUnit.MINUTES); lock.lock(); try { if (recyclable == null) { queue = null; log.info("stop thread %s", Recycler.class.getSimpleName()); return; } if (recyclable.isRecycled()) { queue = null; log.severe("recycling %s again", recyclable); throw new IllegalArgumentException("recycling "+recyclable+" again"); } recyclable.clear(); mapList.add(recyclable.getClass(), recyclable); log.debug("recycled %s", recyclable); } finally { lock.unlock(); } } catch (InterruptedException ex) { } } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy