亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

java多線程教程之如何使用線程池詳解

2024-07-14 08:42:45
字體:
來源:轉載
供稿:網友

為什么要用線程池?

諸如 Web 服務器、數據庫服務器、文件服務器或郵件服務器之類的許多服務器應用程序都面臨處理來自某些遠程來源的大量短小的任務。請求以某種方式到達服務器,這種方式可能是通過網絡協議(例如 HTTP、FTP 或 POP)、通過 JMS 隊列或者可能通過輪詢數據庫。不管請求如何到達,服務器應用程序中經常出現的情況是:單個任務處理的時間很短而請求的數目卻是巨大的。

只有當任務都是同類型并且相互獨立時,線程池的性能才能達到最佳。如果將運行時間較長的與運行時間較短的任務混合在一起,那么除非線程池很大,否則將可能造成擁塞,如果提交的任務依賴于其他任務,那么除非線程池無線大,否則將可能造成死鎖。

例如饑餓死鎖:線程池中的任務需要無限等待一些必須由池中其他任務才能提供的資源或條件。

ThreadPoolExecutor的通用構造函數:(在調用完構造函數之后可以繼續定制ThreadPoolExecutor)

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,     TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,    RejectedExecutionHandler handler){     //...}

飽和策略:

ThreadPoolExecutor允許提供一個BlockingQueue來保存等待執行的任務。

當有界隊列被填滿后,飽和策略開始發揮作用。可以通過調用setRejectedExecutionHandler來修改。

中止是默認的飽和策略,該策略將拋出未檢查的RejectedExecutionException,調用者可以捕獲這個異常,然后根據需求編寫自己的處理代碼。

調用者運行策略實現了一種調節機制,該策略既不會拋棄任務,也不會拋出異常,而是將某些任務回退到調用者,從而降低新任務的流量。

例如對于WebServer,當線程池中的所有線程都被占用,并且工作隊列被填滿后,下一個任務在調用execute時在主線程中執行。

由于執行任務需要一定的時間,因此主線程至少在一段時間內不能提交任何任務,從而使得工作者線程有時間來處理完正在執行的任務。

在這期間,主線程不會調用accept,因此到達的請求將被保存在TCP層的隊列中而不是在應用程序的隊列中,如果持續過載,那么TCP層最終發現它的請求隊列被填滿,同樣會開始拋棄請求。

因此當服務器過載時,這種過載會逐漸向外蔓延開來---從線程池到工作隊列到應用程序再到TCP層,最終到達客戶端,導致服務器在高負載下實現一種平緩的性能降低。

exec.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

當工作隊列被填滿后,沒有預定于的飽和策略來阻塞execute。而通過Semaphore來現在任務的到達率,可以實現。

/** * 設置信號量的上界設置為線程池的大小加上可排隊任務的數量,控制正在執行和等待執行的任務數量。 */public class BoundedExecutor {  private final Executor exec; private final Semaphore semaphore;  public BoundedExecutor(Executor exec,int bound){  this.exec = exec;  this.semaphore = new Semaphore(bound); }  public void submitTask(final Runnable task) throws InterruptedException{  semaphore.acquire();  try{   exec.execute(new Runnable(){    public void run(){     try{      task.run();     }finally{      semaphore.release();     }    }   });  }catch(RejectedExecutionException e){   semaphore.release();  } }}

線程工廠

線程池配置信息中可以定制線程工廠,在ThreadFactory中只定義了一個方法newThread,每當線程池需要創建一個新線程時都會調用這個方法。

public interface ThreadFactory{ Thread newThread(Runnable r);}
// 示例:將一個特定于線程池的名字傳遞給MyThread的構造函數,從而可以再線程轉儲和錯誤日志信息中區分來自不同線程池的線程。 public class MyThreadFactory implements ThreadFactory{  private final String poolName;  public MyThreadFactory(String poolName){  this.poolName = poolName; }  public Thread newThread(Runnable runnable){  return new MyThread(runnable,poolName); }}
// 示例:為線程指定名字,設置自定義UncaughtExceptionHandler向Logger中寫入信息及維護一些統計信息以及在線程被創建或者終止時把調試消息寫入日志。public class MyThread extends Thread{ public static final String default_name = "myThread"; private static volatile boolean debugLifecycle = false; private static final AtomicInteger created = new AtomicInteger(); private static final AtomicInteger alive = new AtomicInteger(); private static final Logger log = Logger.getAnonymousLogger(); public MyThread(Runnable runnable){  this(runnable,default_name); } public MyThread(Runnable runnable, String defaultName) {  super(runnable,defaultName + "-" + created.incrementAndGet());  setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {   @Override   public void uncaughtException(Thread t, Throwable e) {    log.log(Level.SEVERE,"uncaught in thread " + t.getName(), e);    }  }); } public void run(){  boolean debug = debugLifecycle;  if(debug){   log.log(Level.FINE,"created " + getName());  }  try{   alive.incrementAndGet();   super.run();  }finally{   alive.decrementAndGet();   if(debug){    log.log(Level.FINE,"Exiting " + getName());   }  } }}

擴展ThreadPoolExecutor

在線程池完成關閉操作時調用terminated,也就是在所有任務都已經完成并且所有工作者線程也已經關閉后。terminated可以用來釋放Executor在其生命周期里分配的各種資源,此外還可以執行發送通知、記錄日志或者收集finalize統計信息等操作。

示例:給線程池添加統計信息

/** * TimingThreadPool中給出了一個自定義的線程池,通過beforeExecute、afterExecute、terminated等方法來添加日志記錄和統計信息收集。 * 為了測量任務的運行時間,beforeExecute必須記錄開始時間并把它保存到一個afterExecute可用訪問的地方。 * 因為這些方法將在執行任務的線程中調用,因此beforeExecute可以把值保存到一個ThreadLocal變量中。然后由afterExecute來取。 * 在TimingThreadPool中使用了兩個AtomicLong變量,分別用于記錄已處理的任務和總的處理時間,并通過包含平均任務時間的日志消息。 */public class TimingThreadPool extends ThreadPoolExecutor{  public TimingThreadPool(int corePoolSize, int maximumPoolSize,   long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {  super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); }  private final ThreadLocal<Long> startTime = new ThreadLocal<Long>(); private final Logger log = Logger.getLogger("TimingThreadPool"); private final AtomicLong numTasks = new AtomicLong(); private final AtomicLong totalTime = new AtomicLong();  protected void beforeExecute(Thread t,Runnable r){  super.beforeExecute(t, r);  log.fine(String.format("Thread %s: start %s", t,r));  startTime.set(System.nanoTime()); }  protected void afterExecute(Throwable t,Runnable r){  try{   long endTime = System.nanoTime();   long taskTime = endTime - startTime.get();   numTasks.incrementAndGet();   totalTime.addAndGet(taskTime);   log.fine(String.format("Thread %s: end %s, time=%dns", t,r,taskTime));  }finally{   super.afterExecute(r, t);  } }  protected void terminated(){  try{   log.info(String.format("Terminated: avg time=%dns", totalTime.get()/numTasks.get()));  }finally{   super.terminated();  } }}

#筆記內容參考  《java并發編程實戰》

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
2019最新中文字幕| 国产精品久久久久久久久久免费| 日韩av不卡电影| 麻豆国产va免费精品高清在线| 影音先锋欧美在线资源| 在线日韩第一页| 亚洲精品国产免费| 欧美福利视频在线| 欧美日韩另类视频| 黄色91在线观看| 国产精品久久久久久久久借妻| 成人做爰www免费看视频网站| 国产欧美亚洲精品| 尤物tv国产一区| 欧美福利视频网站| 91av在线播放| 国产精品日韩在线一区| 富二代精品短视频| 福利二区91精品bt7086| 亚洲美女视频网站| 日韩成人在线播放| 成人综合网网址| 亚洲成色777777女色窝| 亚洲综合av影视| 97久久精品人人澡人人爽缅北| 国产午夜一区二区| www.日韩免费| 亚洲欧美精品suv| 中文字幕日韩精品有码视频| 日韩欧美在线观看视频| 97在线日本国产| 在线精品国产成人综合| 亚洲国产精品推荐| 17婷婷久久www| 亚洲自拍另类欧美丝袜| 成人精品在线视频| 成人免费福利在线| 久久精品国产欧美亚洲人人爽| 亚洲跨种族黑人xxx| 国产精品99久久久久久www| 欧美成人小视频| 国产福利精品视频| 97国产精品视频人人做人人爱| 久久99久久99精品中文字幕| 97婷婷大伊香蕉精品视频| 久久亚洲国产精品成人av秋霞| 日韩精品视频免费在线观看| 国产精品爽黄69天堂a| 亚洲成人网久久久| 久久国产精品亚洲| 欧美日韩美女在线| 亚洲区免费影片| 97精品视频在线播放| 色99之美女主播在线视频| 日韩精品极品在线观看播放免费视频| 亚洲va欧美va国产综合剧情| 欧洲s码亚洲m码精品一区| 欧美一级片免费在线| 亚洲精品动漫100p| 91热福利电影| 久久久精品视频成人| 午夜免费在线观看精品视频| 黄色成人在线免费| 欧美丰满老妇厨房牲生活| 国产精品69av| 成人免费看吃奶视频网站| 不卡中文字幕av| 亚洲第一视频网| 欧美一区二区大胆人体摄影专业网站| 18久久久久久| 91性高湖久久久久久久久_久久99| 精品香蕉在线观看视频一| 国产在线拍偷自揄拍精品| 日韩美女主播视频| 欧美大奶子在线| 国内精品中文字幕| 日韩经典一区二区三区| 精品国产自在精品国产浪潮| www.久久草.com| 亚洲人成欧美中文字幕| 欧美日韩中文在线观看| 久久成人综合视频| 精品久久久久久久久久久久久| 日韩中文在线中文网三级| 国产极品精品在线观看| 日韩电影免费在线观看中文字幕| 欧美成人激情视频免费观看| 亚洲精品欧美日韩专区| 欧美超级乱淫片喷水| 亚洲人成绝费网站色www| 国产区精品视频| 亚洲成人激情视频| 日韩亚洲欧美成人| 日韩欧美在线中文字幕| 韩国精品美女www爽爽爽视频| 亚洲白拍色综合图区| 成人国产在线激情| 亚洲国产高清自拍| 中文字幕日本欧美| 美女国内精品自产拍在线播放| 97精品国产97久久久久久| 国产精品欧美一区二区三区奶水| 国产成人啪精品视频免费网| 2019国产精品自在线拍国产不卡| 欧美精品video| 午夜精品久久久久久久久久久久| 欧美在线一级视频| 亚洲精品成人久久| 国产乱人伦真实精品视频| 成人激情视频免费在线| 97在线观看免费| 亚洲图片在区色| 国产美女久久精品香蕉69| 欧美综合一区第一页| 亚洲一区二区久久久久久久| 亚洲成人三级在线| 精品高清美女精品国产区| 亚洲精品97久久| 在线观看中文字幕亚洲| 久久久精品国产网站| 久久99精品国产99久久6尤物| 色哟哟网站入口亚洲精品| 亚洲深夜福利网站| 国产成人精品日本亚洲| 最近2019中文字幕mv免费看| 色999日韩欧美国产| 亚洲精品国产精品乱码不99按摩| 亚洲午夜精品久久久久久性色| 成人免费淫片aa视频免费| 一本色道久久88精品综合| 久久久久久久久久婷婷| 尤物yw午夜国产精品视频明星| 欧美亚洲成人精品| 91九色蝌蚪国产| 亚洲第一区中文字幕| 日本乱人伦a精品| 国产中文字幕91| 欧美中文字幕精品| 日韩av在线免费观看一区| 国产精品日韩av| 91久久精品国产91性色| 亚洲黄色www| 5252色成人免费视频| 欧美人在线观看| 欧美大全免费观看电视剧大泉洋| 国产女人18毛片水18精品| 亚洲福利视频免费观看| 久久久999精品| 中文字幕在线观看亚洲| 久久国产精品久久国产精品| 国产精品揄拍一区二区| 性欧美在线看片a免费观看| 欧美午夜片欧美片在线观看| 7m第一福利500精品视频| 97精品欧美一区二区三区| 亚洲精品久久久久久久久久久久| www.日韩系列| 欧美性xxxx极品hd满灌| 成人在线视频福利| 亚洲国产精品人人爽夜夜爽| 久久久亚洲国产| 国产精品久久久久aaaa九色| 欧美日韩在线免费观看| 成人在线小视频|