1. 程式人生 > >執行緒池與工廠模式、代理模式的結合使用

執行緒池與工廠模式、代理模式的結合使用

為了提高程式碼的效率,我們經常會使用到執行緒池,那在實際專案工作中,如何將執行緒池與工廠模式和代理模式結合使用,使我們的程式碼更高效,更具有面象物件的思想,以及維護和拓展性更高呢?

接下來,我將結合下列程式碼講講我平時寫專案時的寫法,至於執行緒池是什麼?工廠模式和代理模式的概念等,大家如何不知道的,可以在網上自己查下,這裡就不做過多累贅的介紹。

         首先,我們先來建立一個執行緒池代理類:

/**
 * des       執行緒池代理類,替執行緒池做一些操作,即可以暴露一些執行緒池本有的方法,
 *            也可以寫一些對執行緒池的拓展方法。
 */
public class ThreadPoolProxy {

    ThreadPoolExecutor mThreadPoolExecutor;
    private int mCorePoolSize;
    private int mMaximumPoolSize;

    public ThreadPoolProxy(int corePoolSize,int maximumPoolSize){
        mCorePoolSize = corePoolSize;
        mMaximumPoolSize = maximumPoolSize;
    }
/**
 * @des 初始化執行緒池
 */
    private void initThreadPoolExecutor(){

        if(mThreadPoolExecutor==null||mThreadPoolExecutor.isShutdown()||mThreadPoolExecutor.isTerminated()){
            synchronized (ThreadPoolProxy.class){
                if(mThreadPoolExecutor==null||mThreadPoolExecutor.isShutdown()||mThreadPoolExecutor.isTerminated()){

                    long keepAliveTime = 0;//這裡不保持時間
                    TimeUnit unit = TimeUnit.MILLISECONDS;//毫秒
                    BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();//無限佇列
                    ThreadFactory threadFactory = Executors.defaultThreadFactory();//預設執行緒工廠

                    RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();//這裡不對異常進行處理
                    mThreadPoolExecutor = new ThreadPoolExecutor(
                            mCorePoolSize,//執行緒池核心數
                            mMaximumPoolSize,//最大執行緒數
                            keepAliveTime,//保持時間
                            unit,//時間單位
                            workQueue,//任務佇列
                            threadFactory,//執行緒工廠
                            handler//異常捕獲器
                            );
                }
            }
        }
    }

    /**
     * @des 提交任務
     * @param task
     * @return 得到非同步執行完成之後的結果
     */
    public Future<?> submit(Runnable task){
        initThreadPoolExecutor();
        return mThreadPoolExecutor.submit(task);

    }
    /**
     * @des 執行任務
     * @param task
     */
    public void execute(Runnable task){
        initThreadPoolExecutor();
        mThreadPoolExecutor.execute(task);
    }

    /**
     * @des 移除任務
     * @param task
     */
    public void remove(Runnable task){
        initThreadPoolExecutor();
        mThreadPoolExecutor.remove(task);
    }
}

在上面程式碼中,初始化執行緒池時,我使用了一個雙重檢查加鎖的寫法,在保證第一次同步初始化的同時,又提高了效能。

實際上,建立完執行緒池代理類之後,我們就可以直接通過new ThreadPoolProxy()來直接呼叫類中方法實現執行緒池的一些功能。但一般情況我不這麼做,而且當需要建立幾個處理不同模組事務的執行緒池時,這種做法就顯得很不可取。

         所以一般我還會建立一個執行緒池代理工廠類來獲取執行緒池代理工廠:

/**
 * des                  建立執行緒池代理的工廠類
 */
public class ThreadPoolProxyFactory {

    public static  ThreadPoolProxy mThreadPoolProxy;

    public static ThreadPoolProxy getThreadPoolProxy(){
        if(mThreadPoolProxy == null){
            synchronized (ThreadPoolProxyFactory.class){
                if(mThreadPoolProxy == null){
                    mThreadPoolProxy = new ThreadPoolProxy(3,3);
                }
            }
        }
        return mThreadPoolProxy;
    }
}

接下來,我們就可以直接通過工廠類,來獲取到執行緒池代理。
public class MainActivity extends AppCompatActivity {

    private String TAG = getClass().getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //通過執行緒池代理工廠類獲取執行緒池代理,再通過執行緒池代理去提交一個任務
        ThreadPoolProxyFactory.getThreadPoolProxy().submit(new MyTask());
    }
    
    class MyTask implements Runnable{
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                Log.d(TAG,"執行緒任務:"+i++);
            }
        }
    }
}

直接執行,可以通過打印出來的Log資訊獲知到我們的執行緒池建立的子執行緒運行了;


這種執行緒池與工廠模式和代理模式的結合在實際的專案開發中常用,也更加提高面向物件的程式設計思想,有利於程式碼的維護和拓展。