問題:當(dāng)每次點(diǎn)擊界面上的item觸發(fā)開啟一個(gè)子線程,去請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù),界面上的item很多,在用戶迅速點(diǎn)擊的情況下, 會(huì)新建n個(gè)子線程, 每個(gè)線程在內(nèi)存中占用1M空間, 消耗非常大,如何優(yōu)化這種多線程任務(wù)?
解決方案: 用線程池去處理這種多線程的任務(wù), 線程池的核心線程個(gè)數(shù)為1 ,用有界隊(duì)列將新的線程添加進(jìn)來,有界隊(duì)列的size 也為1,即在線程池中 只能同時(shí)允許1個(gè)線程運(yùn)行, 1個(gè)線程等待,在將新的線程添加進(jìn)線程池之前, 先將線程池的隊(duì)列清空,具體實(shí)現(xiàn)方案如下:
public class CountRunnable implements Runnable{
@Override
public void run() {
for(int i = 0 ; i < 5 ; i++){
System.out.println(Thread.currentThread().getName()+" i : "+i);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("---------------------------------");
}
}
int corePoolSize = 1;//核心線程個(gè)數(shù)
int maximumPoolSize? = 1;//最大線程個(gè)數(shù)
long keepAliveTime = 5;//線程存活時(shí)間
TimeUnit unit = TimeUnit.SECONDS;
ArrayBlockingQueueworkQueue = new ArrayBlockingQueue<>(1);
ThreadPoolExecutor executor =new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue);
//添加十個(gè)任務(wù)
for(int i = 1 ; i < 10; i++){
BlockingQueuequeue = executor.getQueue();
queue.clear();//添加任務(wù)之前,先將任務(wù)隊(duì)列清空
System.out.println("blockQueue size : "+executor.getQueue().size());
executor.execute(new CountRunnable());
}
System.out.println("## blockQueue size : "+executor.getQueue().size());
上面所做的操作實(shí)際就是:用線程池去處理這種多線程的任務(wù), 線程池的核心線程個(gè)數(shù)為1 ,用有界隊(duì)列將新的線程添加進(jìn)來,有界隊(duì)列的size 也為1,即在線程池中 只能同時(shí)允許1個(gè)線程運(yùn)行, 1個(gè)線程等待,在將新的線程添加進(jìn)線程池之前, 先將線程池的隊(duì)列清空, 輸出的log可以看到, 雖然在運(yùn)行的過程中添加了10個(gè)線程任務(wù), 但是實(shí)際上只運(yùn)行完成了兩個(gè)線程任務(wù):
blockQueue size : 0
blockQueue size : 0
blockQueue size : 0
blockQueue size : 0
blockQueue size : 0
pool-1-thread-1 i : 0
blockQueue size : 0
blockQueue size : 0
blockQueue size : 0
blockQueue size : 0
## blockQueue size : 1
pool-1-thread-1 i : 1
pool-1-thread-1 i : 2
pool-1-thread-1 i : 3
pool-1-thread-1 i : 4
---------------------------------
pool-1-thread-1 i : 0
pool-1-thread-1 i : 1
pool-1-thread-1 i : 2
pool-1-thread-1 i : 3
pool-1-thread-1 i : 4
---------------------------------
通過這種方式, 不管用戶如何點(diǎn)擊界面上的item ,實(shí)際上頁面所需要的數(shù)據(jù)是用戶最后一次點(diǎn)擊item所返回回來的數(shù)據(jù), 這樣就避免了創(chuàng)建n個(gè)不必要的線程任務(wù).