Package javolution.context

Source Code of javolution.context.PoolContext$PoolAllocator

/*
* Javolution - Java(TM) Solution for Real-Time and Embedded Systems
* Copyright (C) 2009 - Javolution (http://javolution.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javolution.context;

import java.lang.ThreadLocal;
import javolution.util.FastMap;
import javolution.util.FastTable;

/**
* <p> This class represents a shared pool context for object
*     allocation/recycling. Unlike {@link HeapContext}, objects recycled
*     can be reused by all threads running in a {@link PoolContext}.[code]
*         // To avoid each new thread to enter a PoolContext, the default
*         // allocator context can be configured to PoolContext.class
*         Thread thread1 = new Thread() {
*            public void run() {
*                PoolContext.enter();
*                try {
*                    ...
*                    myObject = myObjectFactory.object(); // Returns an object potentially recycled by thread2.
*                    ...
*                } finally {
*                    PoolContext.exit();
*                }
*            }};
*        Thread thread2 = new Thread() {
*            public void run() {
*                PoolContext.enter();
*                try {
*                    ...
*                    myObjectFactory.recycle(myObject); // Recycles an object potentially created by thread1.
*                    ...
*                } finally {
*                    PoolContext.exit();
*                }
*            }};
*     [/code]</p>
*
* @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 5.3, March 10, 2009
*/
public class PoolContext extends AllocatorContext {

    /**
     * Holds the factory to allocator mapping (per thread).
     */
    private static final ThreadLocal FACTORY_TO_ALLOCATOR = new ThreadLocal() {

        protected Object initialValue() {
            return new FastMap();
        }
    };
    /**
     * Holds the allocators which have been activated (per thread).
     */
    private static final ThreadLocal ACTIVE_ALLOCATORS = new ThreadLocal() {

        protected Object initialValue() {
            return new FastTable();
        }
    };

    /**
     * Enters a pool context.
     */
    public static void enter() {
         Context.enter(PoolContext.class);
    }

    /**
     * Exits the current pool context.
     *
     * @throws ClassCastException if the context is not a pool context.
     */
    public static void exit() {
         Context.exit(PoolContext.class);
    }

    /**
     * Default constructor.
     */
    public PoolContext() {
    }

    // Overrides.
    protected void deactivate() {
        FastTable allocators = (FastTable) ACTIVE_ALLOCATORS.get();
        for (int i = 0, n = allocators.size(); i < n;) {
            ((Allocator) allocators.get(i++)).user = null;
        }
        allocators.clear();
    }

    // Overrides.
    protected Allocator getAllocator(ObjectFactory factory) {
        final FastMap factoryToAllocator = (FastMap) FACTORY_TO_ALLOCATOR.get();
        PoolAllocator allocator = (PoolAllocator) factoryToAllocator.get(factory);
        if (allocator == null) {
            allocator = new PoolAllocator(factory);
            factoryToAllocator.put(factory, allocator);
        }
        if (allocator.user == null) { // Activate.
            allocator.user = Thread.currentThread();
            FastTable activeAllocators = (FastTable) ACTIVE_ALLOCATORS.get();
            activeAllocators.add(allocator);
        }
        return allocator;
    }

    // Overrides.
    protected void enterAction() {
        getOuter().getAllocatorContext().deactivate();
    }

    // Overrides.
    protected void exitAction() {
        this.deactivate();
    }

    // Holds heap allocator implementation.
    private static final class PoolAllocator extends Allocator {

        private static final FastMap FACTORY_TO_POOL = new FastMap();
        private final ObjectFactory _factory;
        private final FastTable _recycled;

        public PoolAllocator(ObjectFactory factory) {
            _factory = factory;
            synchronized (FACTORY_TO_POOL) {
                FastTable recycled = (FastTable) FACTORY_TO_POOL.get(factory);
                if (recycled == null) {
                    recycled = new FastTable();
                    FACTORY_TO_POOL.put(factory, recycled);
                }
                _recycled = recycled;
            }
        }

        protected Object allocate() {
            if (_recycled.isEmpty()) return _factory.create();
            synchronized (_recycled) {
                return _recycled.removeLast();
            }
        }

        protected void recycle(Object object) {
            if (_factory.doCleanup())
                _factory.cleanup(object);
            synchronized (_recycled) {
               _recycled.addLast(object);
            }
        }

        public String toString() {
            return "Pool allocator for " + _factory.getClass();
        }
    }
}
TOP

Related Classes of javolution.context.PoolContext$PoolAllocator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.