日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java多线程总结五:线程池的原理及实现

發布時間:2025/3/14 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java多线程总结五:线程池的原理及实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、線程池簡介:
??? 多線程技術主要解決處理器單元內多個線程執行的問題,它可以顯著減少處理器單元的閑置時間,增加處理器單元的吞吐能力。????
??? 假設一個服務器完成一項任務所需時間為:T1 創建線程時間,T2 在線程中執行任務的時間,T3 銷毀線程時間。

??? 如果:T1 + T3 遠大于 T2,則可以采用線程池,以提高服務器性能。
??????????????? 一個線程池包括以下四個基本組成部分:
??????????????? 1、線程池管理器(ThreadPool):用于創建并管理線程池,包括 創建線程池,銷毀線程池,添加新任務;
??????????????? 2、工作線程(PoolWorker):線程池中線程,在沒有任務時處于等待狀態,可以循環的執行任務;
??????????????? 3、任務接口(Task):每個任務必須實現的接口,以供工作線程調度任務的執行,它主要規定了任務的入口,任務執行完后的收尾工作,任務的執行狀態等;
??????????????? 4、任務隊列(taskQueue):用于存放沒有處理的任務。提供一種緩沖機制。
????????????????
??? 線程池技術正是關注如何縮短或調整T1,T3時間的技術,從而提高服務器程序性能的。它把T1,T3分別安排在服務器程序的啟動和結束的時間段或者一些空閑的時間段,這樣在服務器程序處理客戶請求時,不會有T1,T3的開銷了。
??? 線程池不僅調整T1,T3產生的時間段,而且它還顯著減少了創建線程的數目,看一個例子:
??? 假設一個服務器一天要處理50000個請求,并且每個請求需要一個單獨的線程完成。在線程池中,線程數一般是固定的,所以產生線程總數不會超過線程池中線程的數目,而如果服務器不利用線程池來處理這些請求則線程總數為50000。一般線程池大小是遠小于50000。所以利用線程池的服務器程序不會為了創建50000而在處理請求時浪費時間,從而提高效率。

??? 代碼實現中并沒有實現任務接口,而是把Runnable對象加入到線程池管理器(ThreadPool),然后剩下的事情就由線程池管理器(ThreadPool)來完成了

?

[java]?view plaincopy
  • package?mine.util.thread;??
  • ??
  • import?java.util.LinkedList;??
  • import?java.util.List;??
  • ??
  • /**?
  • ?*?線程池類,線程管理器:創建線程,執行任務,銷毀線程,獲取線程基本信息?
  • ?*/??
  • public?final?class?ThreadPool?{??
  • ????//?線程池中默認線程的個數為5??
  • ????private?static?int?worker_num?=?5;??
  • ????//?工作線程??
  • ????private?WorkThread[]?workThrads;??
  • ????//?未處理的任務??
  • ????private?static?volatile?int?finished_task?=?0;??
  • ????//?任務隊列,作為一個緩沖,List線程不安全??
  • ????private?List<Runnable>?taskQueue?=?new?LinkedList<Runnable>();??
  • ????private?static?ThreadPool?threadPool;??
  • ??
  • ????//?創建具有默認線程個數的線程池??
  • ????private?ThreadPool()?{??
  • ????????this(5);??
  • ????}??
  • ??
  • ????//?創建線程池,worker_num為線程池中工作線程的個數??
  • ????private?ThreadPool(int?worker_num)?{??
  • ????????ThreadPool.worker_num?=?worker_num;??
  • ????????workThrads?=?new?WorkThread[worker_num];??
  • ????????for?(int?i?=?0;?i?<?worker_num;?i++)?{??
  • ????????????workThrads[i]?=?new?WorkThread();??
  • ????????????workThrads[i].start();//?開啟線程池中的線程??
  • ????????}??
  • ????}??
  • ??
  • ????//?單態模式,獲得一個默認線程個數的線程池??
  • ????public?static?ThreadPool?getThreadPool()?{??
  • ????????return?getThreadPool(ThreadPool.worker_num);??
  • ????}??
  • ??
  • ????//?單態模式,獲得一個指定線程個數的線程池,worker_num(>0)為線程池中工作線程的個數??
  • ????//?worker_num<=0創建默認的工作線程個數??
  • ????public?static?ThreadPool?getThreadPool(int?worker_num1)?{??
  • ????????if?(worker_num1?<=?0)??
  • ????????????worker_num1?=?ThreadPool.worker_num;??
  • ????????if?(threadPool?==?null)??
  • ????????????threadPool?=?new?ThreadPool(worker_num1);??
  • ????????return?threadPool;??
  • ????}??
  • ??
  • ????//?執行任務,其實只是把任務加入任務隊列,什么時候執行有線程池管理器覺定??
  • ????public?void?execute(Runnable?task)?{??
  • ????????synchronized?(taskQueue)?{??
  • ????????????taskQueue.add(task);??
  • ????????????taskQueue.notify();??
  • ????????}??
  • ????}??
  • ??
  • ????//?批量執行任務,其實只是把任務加入任務隊列,什么時候執行有線程池管理器覺定??
  • ????public?void?execute(Runnable[]?task)?{??
  • ????????synchronized?(taskQueue)?{??
  • ????????????for?(Runnable?t?:?task)??
  • ????????????????taskQueue.add(t);??
  • ????????????taskQueue.notify();??
  • ????????}??
  • ????}??
  • ??
  • ????//?批量執行任務,其實只是把任務加入任務隊列,什么時候執行有線程池管理器覺定??
  • ????public?void?execute(List<Runnable>?task)?{??
  • ????????synchronized?(taskQueue)?{??
  • ????????????for?(Runnable?t?:?task)??
  • ????????????????taskQueue.add(t);??
  • ????????????taskQueue.notify();??
  • ????????}??
  • ????}??
  • ??
  • ????//?銷毀線程池,該方法保證在所有任務都完成的情況下才銷毀所有線程,否則等待任務完成才銷毀??
  • ????public?void?destroy()?{??
  • ????????while?(!taskQueue.isEmpty())?{//?如果還有任務沒執行完成,就先睡會吧??
  • ????????????try?{??
  • ????????????????Thread.sleep(10);??
  • ????????????}?catch?(InterruptedException?e)?{??
  • ????????????????e.printStackTrace();??
  • ????????????}??
  • ????????}??
  • ????????//?工作線程停止工作,且置為null??
  • ????????for?(int?i?=?0;?i?<?worker_num;?i++)?{??
  • ????????????workThrads[i].stopWorker();??
  • ????????????workThrads[i]?=?null;??
  • ????????}??
  • ????????threadPool=null;??
  • ????????taskQueue.clear();//?清空任務隊列??
  • ????}??
  • ??
  • ????//?返回工作線程的個數??
  • ????public?int?getWorkThreadNumber()?{??
  • ????????return?worker_num;??
  • ????}??
  • ??
  • ????//?返回已完成任務的個數,這里的已完成是只出了任務隊列的任務個數,可能該任務并沒有實際執行完成??
  • ????public?int?getFinishedTasknumber()?{??
  • ????????return?finished_task;??
  • ????}??
  • ??
  • ????//?返回任務隊列的長度,即還沒處理的任務個數??
  • ????public?int?getWaitTasknumber()?{??
  • ????????return?taskQueue.size();??
  • ????}??
  • ??
  • ????//?覆蓋toString方法,返回線程池信息:工作線程個數和已完成任務個數??
  • ????@Override??
  • ????public?String?toString()?{??
  • ????????return?"WorkThread?number:"?+?worker_num?+?"??finished?task?number:"??
  • ????????????????+?finished_task?+?"??wait?task?number:"?+?getWaitTasknumber();??
  • ????}??
  • ??
  • ????/**?
  • ?????*?內部類,工作線程?
  • ?????*/??
  • ????private?class?WorkThread?extends?Thread?{??
  • ????????//?該工作線程是否有效,用于結束該工作線程??
  • ????????private?boolean?isRunning?=?true;??
  • ??
  • ????????/*?
  • ?????????*?關鍵所在啊,如果任務隊列不空,則取出任務執行,若任務隊列空,則等待?
  • ?????????*/??
  • ????????@Override??
  • ????????public?void?run()?{??
  • ????????????Runnable?r?=?null;??
  • ????????????while?(isRunning)?{//?注意,若線程無效則自然結束run方法,該線程就沒用了??
  • ????????????????synchronized?(taskQueue)?{??
  • ????????????????????while?(isRunning?&&?taskQueue.isEmpty())?{//?隊列為空??
  • ????????????????????????try?{??
  • ????????????????????????????taskQueue.wait(20);??
  • ????????????????????????}?catch?(InterruptedException?e)?{??
  • ????????????????????????????e.printStackTrace();??
  • ????????????????????????}??
  • ????????????????????}??
  • ????????????????????if?(!taskQueue.isEmpty())??
  • ????????????????????????r?=?taskQueue.remove(0);//?取出任務??
  • ????????????????}??
  • ????????????????if?(r?!=?null)?{??
  • ????????????????????r.run();//?執行任務??
  • ????????????????}??
  • ????????????????finished_task++;??
  • ????????????????r?=?null;??
  • ????????????}??
  • ????????}??
  • ??
  • ????????//?停止工作,讓該線程自然執行完run方法,自然結束??
  • ????????public?void?stopWorker()?{??
  • ????????????isRunning?=?false;??
  • ????????}??
  • ????}??
  • }??
  • ?

    測試代碼:

    [java]?view plaincopy
  • package?mine.util.thread;??
  • ??
  • //測試線程池??
  • public?class?TestThreadPool?{??
  • ????public?static?void?main(String[]?args)?{??
  • ????????//?創建3個線程的線程池??
  • ????????ThreadPool?t?=?ThreadPool.getThreadPool(3);??
  • ????????t.execute(new?Runnable[]?{?new?Task(),?new?Task(),?new?Task()?});??
  • ????????t.execute(new?Runnable[]?{?new?Task(),?new?Task(),?new?Task()?});??
  • ????????System.out.println(t);??
  • ????????t.destroy();//?所有線程都執行完成才destory??
  • ????????System.out.println(t);??
  • ????}??
  • ??
  • ????//?任務類??
  • ????static?class?Task?implements?Runnable?{??
  • ????????private?static?volatile?int?i?=?1;??
  • ??
  • ????????@Override??
  • ????????public?void?run()?{//?執行任務??
  • ????????????System.out.println("任務?"?+?(i++)?+?"?完成");??
  • ????????}??
  • ????}??
  • }??

  • ?

    運行結果:

    WorkThread number:3? finished task number:0? wait task number:6
    任務 1 完成
    任務 2 完成
    任務 3 完成
    任務 4 完成
    任務 5 完成
    任務 6 完成
    WorkThread number:3? finished task number:6? wait task number:0

    分析:由于并沒有任務接口,傳入的可以是自定義的任何任務,所以線程池并不能準確的判斷該任務是否真正的已經完成(真正完成該任務是這個任務的run方法執行完畢),只能知道該任務已經出了任務隊列,正在執行或者已經完成。

    ?

    2、java類庫中提供的線程池簡介:

    ???? java提供的線程池更加強大,相信理解線程池的工作原理,看類庫中的線程池就不會感到陌生了。

    ?


    ?

    ?

    ?

    ?

    其他具體內容查看jdk幫助或看jdk源代碼吧。。。

    參考文章:http://hi.baidu.com/obullxl/blog/item/ee50ad1ba8e8ff1f8718bf66.html

    轉載于:https://www.cnblogs.com/kinghitomi/archive/2012/01/19/2327418.html

    總結

    以上是生活随笔為你收集整理的java多线程总结五:线程池的原理及实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。