性能優化14_多線程優化(編輯中)

Android性能優化彙總

一 生產者與消費者模式

public class ThreadTest {

    //產品
    static class ProductObject {
        //線程操作變量可見
        public volatile static String value;
    }

    //生產者線程
    static class Producer extends Thread {
        Object lock;

        public Producer(Object lock) {
            this.lock = lock;
        }

        @Override
        public void run() {
            //不斷生產產品
            while (true) {
                synchronized (lock) {//互斥鎖
                    //產品還沒有被消費,等待
                    if (ProductObject.value != null) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    //產品已經消費完成,生產新的產品
                    ProductObject.value = "NO:" + System.currentTimeMillis();
                    System.out.print("生產產品:" + ProductObject.value);
                    lock.notify();
                }
            }
        }
    }

    //消費者線程
    static class Consumer extends Thread {
        Object lock;

        public  Consumer(Object lock){
            this.lock = lock;
        }

        @Override
        public void run() {
            while (true){
                synchronized (lock){
                    //沒有產品可以消費
                    if(ProductObject.value == null){
                        //等待,阻塞
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    System.out.print("消費產品:"+ProductObject.value);
                    ProductObject.value = null;
                    lock.notify();//消費完成,通知生產者繼續生產
                }
            }
        }
    }

    public static void main(String[] args){
        Object lock = new Object();
        new Producer(lock).start();
        new Consumer(lock).start();
    }
}

二 FutureTask 的便利性

異步任務執行的結果,主線程無法輕易的獲取
1.獲取異步任務的返回值
2.監聽異步任務的執行完畢
3.取消異步任務

public static void main(String[] args) {
        Task work = new Task();
        FutureTask<Integer> future = new FutureTask<Integer>(work){
            @Override
            protected void done() {
                try {
                    System.out.println("done:"+get());
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        //線程池(使用了預定義的配置)
        ExecutorService executor = Executors.newCachedThreadPool();
        executor.execute(future);

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //取消異步任務
        future.cancel(true);

        try {
            //阻塞,等待異步任務執行完畢
            System.out.println(future.get()); //獲取異步任務的返回值
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    //異步任務
    static class Task implements Callable<Integer>{

        //返回異步任務的執行結果
        @Override
        public Integer call() {
            int i = 0;
            for(;i < 10;i++){
                System.out.println(Thread.currentThread().getName()+"_"+i);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return i;
        }
    }
}

三 AsyncTask的侷限性

doBackground(call)
call的返回值在Future的done方法中獲取

->onPostExecute

new MyTask().execute();

實例化:
new AsyncTask() -> new FutureTask()

執行:
Executor.execute(mFuture) -> SerialExecutor.myTasks(隊列)
-> (線程池)THREAD_POOL_EXECUTOR.execute

線程池中的所有線程,爲了執行異步任務

CORE_POOL_SIZE 核心線程數
MAXIMUM_POOL_SIZE 最大線程數量
KEEP_ALIVE 1s閒置回收
TimeUnit.SECONDS 時間單位
sPoolWorkQueue 異步任務隊列
sThreadFactory 線程工廠

如果當前線程池中的數量小於corePoolSize,創建並添加的任務。
如果當前線程池中的數量等於corePoolSize,緩衝隊列 workQueue未滿,那麼任務被放入緩衝隊列、等待任務調度執行。
如果當前線程池中的數量大於corePoolSize,緩衝隊列workQueue已滿,並且線程池中的數量小於maximumPoolSize,新提交任務會創建新線程執行任務。
如果當前線程池中的數量大於corePoolSize,緩衝隊列workQueue已滿,並且線程池中的數量等於maximumPoolSize,新提交任務由Handler處理。
當線程池中的線程大於corePoolSize時,多餘線程空閒時間超過keepAliveTime時,會關閉這部分線程。

public static final Executor THREAD_POOL_EXECUTOR
= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

1.線程池容量不夠拋出異常
2.內存泄露
3.一個線程,一個異步任務(?)

 public static void main(String[] args) {
        int CPU_COUNT = Runtime.getRuntime().availableProcessors();
        int CORE_POOL_SIZE = CPU_COUNT + 1;//5
        int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; //9
        int KEEP_ALIVE = 1;

        //任務隊列(128)
        final BlockingDeque<Runnable> sPoolWorkQueue = new LinkedBlockingDeque<>(128);

        //線程工廠
        ThreadFactory sThreaFactory = new ThreadFactory() {

            private final AtomicInteger mCount = new AtomicInteger(1);

            @Override
            public Thread newThread(@NonNull Runnable r) {
                String name = "Thread #" + mCount.getAndIncrement();
                System.out.println(name);
                return new Thread(r, name);
            }
        };
        //線程池
        Executor THREAD_POOL_EXECUTOR
                = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
                TimeUnit.SECONDS, sPoolWorkQueue, sThreaFactory);
        //執行異步任務
        //如果當前線程池中的數量大於corePoolSize,緩衝隊列workQueue已滿,
        //並且線程池中的數量等於maximumPoolSize,新提交任務由Handler處理。
        //RejectedExecutionException
        for (int i = 0; i < 200; i++) {
            //相當於new AsyncTask().execute();
            THREAD_POOL_EXECUTOR.execute(new MyTask());
        }

    }


    static class MyTask implements Runnable {

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
			/*while(true){
				try {
					System.out.println(Thread.currentThread().getName());
					//Thread.sleep(1000);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}*/
        }

    }
發佈了231 篇原創文章 · 獲贊 75 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章