Body Code
Import java.util.list;import java.util.map;import java.util.concurrent.concurrenthashmap;import java.util.concurrent.CopyOnWriteArrayList;import java.util.concurrent.ExecutorService;import java.util.concurrent.executors;import java.util.concurrent.locks.condition;import java.util.concurrent.locks.reentrantlock;/** * register one or more consumer threads map. * run a registered thread when there is data in the cache * <p> * register the thread in need to do delete the element processing in the map * </p> * otherwise if it is empty, wait for . * * @param <K> * the key type * @param <V> * the value type * @author ming.peng * @ date 2013-12-19 * @since 4.0.0 */@SuppressWarnings ("Serial") public class consumconcurrenthashmap<k, v> extends concurrenthashmap<k, v> {/** the lock, is used for synchronization when the current thread changed value changes. */private final reentrantlock lock = new reentrantlock ();/** condition for waiting takes */private final condition notempty = Lock.newcondition ();/** The thread pool is set by default and is used to perform task, . */private executorservice executor = executors.newfixedthreadpool (5);/** the runnables. */private final list <ConsumerRunnable> runnables = new CopyOnWriteArrayList<ConsumerRunnable> ();/* * * instantiates a new drives concurrent hash map. */public Consumconcurrenthashmap () {super ();} /** * instantiates a new drives concurrent hash map. * * @param &NBSP;INITIALCAPACITY&NBSP;*&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&Nbsp; the initial capacity * @param loadFactor * the load factor * @param concurrencylevel * the Concurrency level */public consumconcurrenthashmap (int initialcapacity, float Loadfactor, int concurrencylevel) {super (initialcapacity, loadfactor, Concurrencylevel);} /** * instantiates a new drives concurrent hash map. * * @param initialCapacity * the initial capacity * @param loadFactor * the load factor */public consumconcurrenthashmap (INT&NBSP;INITIALCAPACITY,&NBSP;FLOat loadfactor) {super (initialcapacity, loadfactor);} /** * instantiates a new drives concurrent hash map. * * @param initialCapacity * the initial capacity */public consumconcurrenthashmap (int initialCapacity) {super (initialcapacity);} /** * instantiates a new drives concurrent hash map. * * @param m * the m */public consumconcurrenthashmap (map<? extends k, ? extends v> m) {super (m);} /** * gets the executor. * * @return the executor */public executorservice getexecutor () {return executor;} /** * sets the executor. * * @param executor * the New executor */public void setexecutor (Executorservice executor) {this.executor = executor;} /** * regsiter runnable. * * @param runnable * the runnable */public void Regsiterrunnable (runnable runnable) {consumerrunnable run = new consumerrunnable (runnable); This.runnables.add (run); Executor.execute (run);} /** * regsiter runnable. * * @param runName * the run name * @param runnable * the runnable */public Void regsiterrunnable (String runname, runnable runnable) {consumerrunnable run = new consumerrunnable (runName, runnable ); This.runnables.add (run); Executor.execute (run);} /** * removes threads, but does not immediately end threads * Removes the runnable. * * @param runnable * the runnable */public void removerunnable (String runname) {for (consumerrunnable run : this.runnables) {if (Null != run.getrunname () && run.getrunname (). Equals (Runname)) {run.setactive (false); // mark thread exits This.runnables.remove (run); // Removes the thread object from the queue}}}/** * deletes the thread, but does not immediately end the thread * removes the runnable. * * @ param runnable * the Runnable */public void removerunnable (runnable runnable) {for (consumerrunnable run : this.runnables) {if (run.getrunnable () equals (runnable) ) {run.setactive (false); // tag thread exits This.runnables.remove (run); // removes the thread object from the queue}}}/* * (non-javadoc) * * @see java.util.concurrent.concurrenthashmap#put ( Java.lang.object, * java.lang.object) */@Overridepublic v put (k key, v value) {v v = super.put (key, value); Notifyconsumerrunnables (); return v;} /* * (non-javadoc) * * @see java.util.concurrent.concurrenthashmap#putifabsent ( Java.lang.object, * java.lang.object) */@Overridepublic v putifabsent (K key, v value) {v v = super.putifabsent (key, value); NotifyConsumerRunnables (); Return v;} /* * (non-javadoc) * * @see java.util.concurrent.concurrenthashmap#putall ( JAVA.UTIL.MAP) */@OverridEpublic void putall (map<? extends k, ? extends v> m) { Super.putall (m); Notifyconsumerrunnables ();} /** * notify consumer threads */private void notifyconsumerrunnables () {lock.lock ();try{if (This.size () > this.runnables.size () * 1000) { Notempty.signalall ();} else {notempty.signal ();}} Finally{lock.unlock ();}} /** * Consumer Threads * * @author [email protected] * @Description * @Date 2015 July 17 PM 6:00:46 */protected final class consumerrunnable implements runnable {/** the run name. */private string runname;/** the runnable. */private runnable runnable;/** the isnow. Indicates whether the task is resumed, false indicates that the task is not performed, and true executes */private boolean isnow = true;/** the isactive, identifies whether the thread is running, false stops running, and true runs. */private boolean isactive = true;/** * instantiates a new drives runnable. */private consumerrunnable () {}/** * Instantiates a new drives runnable. * * @param runnable * the runnable */private consumerrunnable (runnable runnable) {super (); this.runnable = runnable ;} /** * instantiates a new drives runnable. * * @param runname * the run name * @param runnable * the runnable */private consumerrunnable (string runname, runnable runnable) { Super (); This.runnable&nbsP;= runnable;this.runname = runname;} /** will register in the runnable execution #run () method, after completion to see if there is a need for a supplementary mechanism. */public void run () {while ( this.isactive) {lock.lock ();try {if (ConsumConcurrentHashMap.this.isEmpty ()) { Notempty.await ();} if (Isnow) {runnable.run ();}} catch (exception e) {e.printstacktrace ();} finally {lock.unlock ();}}} Public boolean isnow () {return isnow;} Public void setnow (Boolean isnow) {this.isnow = isnow;} /** * gets the active. * * @return */public boolean IsActive () {return isactive;} /** * sets the active. * * @param isActive */public Void setactive (boolean isactive) {this.isactive = isactive;} /** * gets the run name. * * @return the run name&nbsP;*/public string getrunname () {return runname;} /** * sets the run name. * * @param runName * the new run name */public void setrunname (String runname) {this.runname = runname;} /** * gets the runnable. * * @return the runnable */public runnable getrunnable () {return runnable;} /** * sets the runnable. * * @param runnable * the new runnable */public void Setrunnable (runnable runnable) {this.runnable = runnable;}} /** * Stop All tasks, the executing task will continue to execute, close the thread pool */public void shutdown () {// end all thread marks for (Consumerrunnable run : runnables)   {run.setactive (false);} If there is a dormant thread, wake up all threads, execute, exit the Run Method Lock.lock (); Try{notempty.signalall ();} Finally{lock.unlock ();} Close Thread executor Executor.shutdown ();} /** * stops all tasks, attempts to stop the executing thread, closes the thread pool */public list<runnable> shutdownnow () {// marks the end of all threads for (Consumerrunnable run : runnables) {run.setactive (false); Run.setnow (false); // whether to perform the task at the end}// if there is a dormant thread, wake all threads, execute, exit the Run Method Lock.lock (); try{ Notempty.signalall ();} Finally{lock.unlock ();} Close Thread executor Return executor.shutdownnow ();}}
2. Test
import java.util.map.entry;import java.util.random;import java.util.uuid;import org.apache.commons.lang3.randomstringutils;import org.slf4j.logger;import org.slf4j.loggerfactory; public class test {private static final logger logger = Loggerfactory.getlogger (Test.class);p rivate static final consumconcurrenthashmap<string, String> map = new ConsumConcurrentHashMap<> ();p ublic static void main (String[] args) {runnable runnable = new runnable () {Random R = new random (); @Overridepublic void run () {long s = System.currenttimemillis (); Long e = 0l;while ((E = system.currenttimemillis ()) - s < 10 * 60 * 1000) {map.put (Uuid.randomuuid (). toString (), Randomstringutils.randomalphanumeric (5));//tRy {//long nextlong = r.nextint,//thread.sleep (Nextlong);//} catch ( Interruptedexception es) {//es.printstacktrace ();/}}}; Thread thread = new thread (runnable); Thread.Start (); Map.regsiterrunnable (new Runnable () {private int i = 0; @Overridepublic void run () {i++;for (Entry <string, string> entry : map.entryset ()) {logger.info (i + "\ T" + entry.getkey () + "\ T" + entry.getvalue () + "\ T" + map.size ()); Map.Remove (Entry.getkey ());}}); Map.regsiterrunnable (new runnable () {private int i = 0; @Overridepublic void run () {i++;for (Entry<string, string> entry : map.entryset ()) { Logger.info (i + "\ T" + entry.getkey () + "\ T" + entry.getvalue () + "\ T" + map.size ()); Map.Remove (Entry.getkey ());}}); Try {thread.join ();} catch (interruptedexception e) {e.printstacktrace ();} Map.shutdown ();}}
Map proactively notifies thread consumption