package com.oneliang.util.concurrent;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import com.oneliang.Constant;
import com.oneliang.util.logging.Logger;
import com.oneliang.util.logging.LoggerManager;

/**
 * it will process all resources which are in queue when interrupt
 * ResourceQueueThread
 * 
 * @param <T>
 */
public class ResourceQueueThread<T extends Object> implements Runnable {

    private static final Logger logger = LoggerManager.getLogger(ResourceQueueThread.class);

    private Queue<T> resourceQueue = null;
    private Thread thread = null;
    private ResourceProcessor<T> resourceProcessor = null;
    private boolean needToInterrupt = false;

    /**
     * constructor
     * 
     * @param resourceProcessor
     */
    public ResourceQueueThread(ResourceProcessor<T> resourceProcessor) {
        this.resourceProcessor = resourceProcessor;
        this.resourceQueue = new ConcurrentLinkedQueue<T>();
    }

    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                if (!this.resourceQueue.isEmpty()) {
                    T resource = this.resourceQueue.poll();
                    if (this.resourceProcessor != null) {
                        this.resourceProcessor.process(resource);
                    }
                } else {
                    if (this.needToInterrupt) {
                        this.realInterrupt();
                    }
                    synchronized (this) {
                        // double check,for the scene which notify first
                        if (this.needToInterrupt) {
                            this.realInterrupt();
                        }
                        this.wait();
                    }
                }
            } catch (InterruptedException e) {
                logger.verbose("need to interrupt:" + e.getMessage());
                Thread.currentThread().interrupt();
            } catch (Exception e) {
                logger.error(Constant.Base.EXCEPTION, e);
            }
        }
    }

    /**
     * start
     */
    public synchronized void start() {
        if (this.thread == null) {
            this.thread = new Thread(this);
            this.thread.start();
        }
    }

    /**
     * interrupt
     */
    public void interrupt() {
        this.needToInterrupt = true;
        synchronized (this) {
            this.notify();
        }
    }

    /**
     * real interrupt
     */
    private void realInterrupt() {
        if (this.thread != null) {
            this.thread.interrupt();
            this.thread = null;
            this.resourceQueue = null;
            this.resourceProcessor = null;
            this.needToInterrupt = false;
        }
    }

    /**
     * @param resource
     *            the resource to add
     */
    public void addResource(T resource) {
        if (resource != null) {
            this.resourceQueue.add(resource);
            synchronized (this) {
                this.notify();
            }
        }
    }

    public abstract static interface ResourceProcessor<T extends Object> {

        /**
         * process the resource
         * 
         * @param resource
         */
        public abstract void process(T resource);
    }
}

@@ -581,32 +581,167 @@
  thread = null;%0A
+    // always binding in self instance(ResourceQueueThread),finalize self%0A    // instance will set null(release the resourceProcessor)%0A
     private Reso
@@ -775,32 +775,32 @@
 ocessor = null;%0A
-
     private bool
@@ -1033,69 +1033,8 @@
 or;%0A
-        this.resourceQueue = new ConcurrentLinkedQueue%3CT%3E();%0A
     
@@ -2215,24 +2215,141 @@
 d start() %7B%0A
+        if (this.resourceQueue == null) %7B%0A            this.resourceQueue = new ConcurrentLinkedQueue%3CT%3E();%0A        %7D%0A
         if (
@@ -2859,51 +2859,8 @@
 ll;%0A
-            this.resourceProcessor = null;%0A
     
@@ -3182,32 +3182,32 @@
 ;%0A            %7D%0A
-
         %7D%0A    %7D%0A
@@ -3199,32 +3199,159 @@
        %7D%0A    %7D%0A%0A
+    /**%0A     * finalize%0A     */%0A    protected void finalize() throws Throwable %7B%0A        this.resourceProcessor = null;%0A    %7D%0A%0A
     public abstr

optimize code again