java ThreadPool

package com.karl.threadpool;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MyThreadPool {

    List<MyTask> tasks = Collections.synchronizedList(new ArrayList<MyTask>());

    private static MyThreadPool instance = MyThreadPool.getInstance();

    public static MyThreadPool getInstance() {
        if (instance == null) {
            instance = new MyThreadPool();

        }
        return instance;
    }

    private WorkThread[] threads;

    private MyThreadPool() {
        threads = new WorkThread[10];
        for (int i = 0; i < 10; i++) {
            threads[i] = new WorkThread();
        }
    }

    public void addTask(MyTask task) {
        synchronized (tasks) {
            tasks.add(task);
            tasks.notifyAll();
        }
    }

    class WorkThread extends Thread {

        public WorkThread() {
            start();
        }

        @Override
        public void run() {
            while (true) {
                synchronized (tasks) {
                    if (tasks.isEmpty()) {
                        try {
                            // When call the method wait or notify of a Object,
                            // must ensure the Object is synchronized.
                            // Here let the Thread which use the object wait a
                            // while.
                            tasks.wait(20);
                            continue;
                        } catch (InterruptedException e) {
                        }
                    }
                    MyTask r = tasks.remove(0);
                    if (r != null) {
                        if (r.needRunImmde()) {
                            new Thread(r).start();
                        } else {
                            r.run();
                        }
                    }
                }
            }
        }
    }

}
package com.karl.threadpool;

public abstract class MyTask implements Runnable{
    protected abstract boolean needRunImmde();
    public void run(){
        
    }
}
package com.karl.threadpool;

public class PrintNumber extends MyTask {
    
    private int index;
    private boolean needRunImmde=false;
    
    public boolean isNeedRunImmde() {
        return needRunImmde;
    }

    public void setNeedRunImmde(boolean needRunImmde) {
        this.needRunImmde = needRunImmde;
    }

    public PrintNumber(int index){
        this.index=index;
    }

    @Override
    protected boolean needRunImmde() {
        // TODO Auto-generated method stub
        return needRunImmde;
    }
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println(index);
    }

}
package com.karl.threadpool;

public class Test {
    public static void main(String[] args) throws InterruptedException {
        
        for (int i = 0; i < 10; i++) {
            PrintNumber pn = new PrintNumber(i);
            if((i%2)==0){
                pn.setNeedRunImmde(false);
            }
            
            MyThreadPool.getInstance().addTask(pn);
        }
        Thread.sleep(10000L);
        for (int i = 0; i < 10; i++) {
            PrintNumber pn = new PrintNumber(i);
            if((i%2)==0){
                pn.setNeedRunImmde(false);
            }
            
            MyThreadPool.getInstance().addTask(pn);
        }
    }
}