導航:首頁 > 編程語言 > java線程池連接池

java線程池連接池

發布時間:2022-05-14 01:49:03

『壹』 java 連接池 和線程池 之間存在什麼關系么

只能說兩者的原理差不多,都是建立一個池,把連接或者線程放進去,但是兩者並無聯系

『貳』 java線程連接池問題

連接池只是管理一堆的
"連接
",而不是管理怎麼樣去連接,像odbc,jdbc說的只是如何與資料庫連接.連接管理
"連接
",並不是每次要與資料庫連接就創建一次伺服器去數據的連接,而是從連接
"池
"里取一個連接出來,用完後就放回連接池裡,這個連接差沒有與資料庫斷開.因為每次與資料庫創建連接會花費很大的資源.
連接池:連接a,連接b,連接c,連接d...連接一開始就會先與資料庫創建一堆連接,到底多少個可以在配置連接池的時候去設定.
當程序要用連接的時候,就從這個池裡取一個連接出去,用完了再放回連接池
代碼google下

『叄』 啥時候會使用線程池

編者註:Java中的線程池是運用場景最多的並發組件,幾乎所有需要非同步或並發執行任務的程序都可以使用線程池。

在開發過程中,合理地使用線程池能夠帶來至少以下幾個好處。

降低資源消耗:通過重復利用已創建的線程降低線程創建和銷毀造成的消耗。
提高響應速度:當任務到達時,任務可以不需要等到線程創建就能立即執行。
提高線程的可管理性:線程是稀缺資源,如果無限制地創建,不僅會消耗系統資源,還會降低系統的穩定性,使用線程池可以進行統一分配、調優和監控。但是,要做到合理利用線程池,必須了解其實現原理。
代碼解耦:比如生產者消費者模式。
線程池實現原理
當提交一個新任務到線程池時,線程池的處理流程如下:

如果當前運行的線程少於corePoolSize,則創建新線程來執行任務(注意,執行這一步驟需要獲取全局鎖)。
如果運行的線程等於或多於corePoolSize,則將任務加入BlockingQueue。
如果無法將任務加入BlockingQueue(隊列已滿),則創建新的線程來處理任務(注意,執行這一步驟也需要獲取全局鎖)。
如果創建新線程將使當前運行的線程數超出maximumPoolSize,該任務將被拒絕,並調用相應的拒絕策略來處理(RejectedExecutionHandler.rejectedExecution()方法,線程池默認的飽和策略是AbortPolicy,也就是拋異常)。
ThreadPoolExecutor採取上述步驟的總體設計思路,是為了在執行execute()方法時,盡可能地避免獲取全局鎖(那將會是一個嚴重的可伸縮瓶頸)。在ThreadPoolExecutor完成預熱之後(當前運行的線程數大於等於corePoolSize),幾乎所有的execute()方法調用都是執行步驟2,而步驟2不需要獲取全局鎖。

線程池任務 拒絕策略包括 拋異常、直接丟棄、丟棄隊列中最老的任務、將任務分發給調用線程處理。

線程池的創建:通過ThreadPoolExecutor來創建一個線程池。

new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, runnableTaskQueue, handler);
創建一個線程池時需要輸入以下幾個參數:

corePoolSize(線程池的基本大小):當提交一個任務到線程池時,線程池會創建一個線程來執行任務,即使其他空閑的基本線程能夠執行新任務也會創建線程,等到線程池的線程數等於線程池基本大小時就不再創建。如果調用了線程池的prestartAllCoreThreads()方法,線程池會提前創建並啟動所有基本線程。
maximumPoolSize(線程池最大數量):線程池允許創建的最大線程數。如果隊列滿了,並且已創建的線程數小於最大線程數,則線程池會再創建新的線程執行任務。值得注意的是,如果使用了無界的任務隊列這個參數就沒什麼效果。
keepAliveTime(線程活動保持時間):線程池的工作線程空閑後,保持存活的時間。所以,如果任務很多,並且每個任務執行的時間比較短,可以調大時間,提高線程的利用率。
TimeUnit(線程活動保持時間的單位):可選的單位有天(DAYS)、小時(HOURS)、分鍾(MINUTES)、毫秒(MILLISECONDS)、微秒(MICROSECONDS,千分之一毫秒)和納秒(NANOSECONDS,千分之一微秒)。
runnableTaskQueue(任務隊列):用於保存等待執行的任務的阻塞隊列。可以選擇以下幾個阻塞隊列。
- ArrayBlockingQueue:是一個基於數組結構的有界阻塞隊列,此隊列按FIFO(先進先出)原則對元素進行排序。
LinkedBlockingQueue:一個基於鏈表結構的阻塞隊列,此隊列按FIFO排序元素,吞吐量通常要高於ArrayBlockingQueue。靜態工廠方法Executors.newFixedThreadPool()使用了這個隊列。
SynchronousQueue:一個不存儲元素的阻塞隊列。每個插入操作必須等到另一個線程調用移除操作,否則插入操作一直處於阻塞狀態,吞吐量通常要高於LinkedBlockingQueue,靜態工廠方法Executors.newCachedThreadPool使用了這個隊列。
PriorityBlockingQueue:一個具有優先順序的無界阻塞隊列。
線程的狀態
在HotSpot VM線程模型中,Java線程被一對一映射到本地系統線程,Java線程啟動時會創建一個本地系統線程;當Java線程終止時,這個本地系統線程也會被回收。操作系統調度所有線程並把它們分配給可用的CPU。

thread運行周期中,有以下6種狀態,在 java.lang.Thread.State 中有詳細定義和說明:

// Thread類
public enum State {
/**
* 剛創建尚未運行
*/
NEW,

/**
* 可運行狀態,該狀態表示正在JVM中處於運行狀態,不過有可能是在等待其他資源,比如CPU時間片,IO等待
*/
RUNNABLE,

/**
* 阻塞狀態表示等待monitor鎖(阻塞在等待monitor鎖或者在調用Object.wait方法後重新進入synchronized塊時阻塞)
*/
BLOCKED,

/**
* 等待狀態,發生在調用Object.wait、Thread.join (with no timeout)、LockSupport.park
* 表示當前線程在等待另一個線程執行某種動作,比如Object.notify()、Object.notifyAll(),Thread.join表示等待線程執行完成
*/
WAITING,

/**
* 超時等待,發生在調用Thread.sleep、Object.wait、Thread.join (in timeout)、LockSupport.parkNanos、LockSupport.parkUntil
*/
TIMED_WAITING,

/**
*線程已執行完成,終止狀態
*/
TERMINATED;
}
線程池操作
向線程池提交任務,可以使用兩個方法向線程池提交任務,分別為execute()和submit()方法。execute()方法用於提交不需要返回值的任務,所以無法判斷任務是否被線程池執行成功。通過以下代碼可知execute()方法輸入的任務是一個Runnable類的實例。

threadsPool.execute(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
}
});
submit()方法用於提交需要返回值的任務。線程池會返回一個future類型的對象,通過這個future對象可以判斷任務是否執行成功,通過future的get()方法來獲取返回值,future的get()方法會阻塞當前線程直到任務完成,而使用get(long timeout,TimeUnit unit)方法則會阻塞當前線程一段時間後立即返回,這時候有可能任務還沒有執行完。

Future<Object> future = executor.submit(harReturnValuetask);
try {
Object s = future.get();
} catch (InterruptedException e) {
// 處理中斷異常
} catch (ExecutionException e) {
// 處理無法執行任務異常
} finally {
// 關閉線程池
executor.shutdown();
}
合理配置線程池
要想合理配置線程池,必須先分析任務的特點,可以從以下幾個角度分析:

任務的性質:CPU密集型任務、IO密集型任務和混合型任務。
任務的優先順序:高、中和低。
任務的執行時間:長、中和短。
任務的依賴性:是否依賴其他系統資源,如資料庫連接。
性質不同的任務可以用不同規模的線程池分開處理。CPU密集型任務應配置盡可能少的線程,如配置Ncpu+1個線程的線程池。由於IO密集型任務線程並不是一直在執行任務,則應配置多一點線程,如2*Ncpu。混合型的任務,如果可以拆分,將其拆分成一個CPU密集型任務和一個IO密集型任務,只要這兩個任務執行的時間相差不是太大,那麼分解後執行的吞吐量將高於串列執行的吞吐量。如果這兩個任務執行時間相差太大,則沒必要進行分解。可以通過Runtime.getRuntime().availableProcessors()方法獲得當前設備的CPU個數。

優先順序不同的任務可以使用優先順序隊列PriorityBlockingQueue來處理。它可以讓優先順序高的任務先執行。執行時間不同的任務可以交給不同規模的線程池來處理,或者可以使用優先順序隊列,讓執行時間短的任務先執行。依賴資料庫連接池的任務,因為線程提交SQL後需要等待資料庫返回結果,等待的時間越長,則CPU空閑時間就越長,那麼線程數應該設置得越大,這樣才能更好地利用CPU。

線程池中線程數量未達到coreSize時,這些線程處於什麼狀態?

這些線程處於RUNNING或者WAITING,RUNNING表示線程處於運行當中,WAITING表示線程阻塞等待在阻塞隊列上。當一個task submit給線程池時,如果當前線程池線程數量還未達到coreSize時,會創建線程執行task,否則將任務提交給阻塞隊列,然後觸發線程執行。(從submit內部調用的代碼也可以看出來)

ScheledThreadPoolExecutor

ScheledThreadPoolExecutor繼承自ThreadPoolExecutor。它主要用來在給定的延遲之後運行任務,或者定期執行任務。
ScheledThreadPoolExecutor的功能與Timer類似,但
ScheledThreadPoolExecutor功能更強大、更靈活。Timer對應的是單個後台線程,而
ScheledThreadPoolExecutor可以在構造函數中指定多個對應的後台線程數。

ScheledThreadPoolExecutor繼承自ThreadPoolExecutor,
ScheledThreadPoolExecutor和ThreadPoolExecutor的區別是,ThreadPoolExecutor獲取任務時是從BlockingQueue中獲取的,而
ScheledThreadPoolExecutor是從DelayedWorkQueue中獲取的(注意,DelayedWorkQueue是BlockingQueue的實現類)。

ScheledThreadPoolExecutor把待調度的任務(ScheledFutureTask)放到一個DelayQueue中,其中ScheledFutureTask主要包含3個成員變數:

sequenceNumber:任務被添加到ScheledThreadPoolExecutor中的序號;
time:任務將要被執行的具體時間;
period:任務執行的間隔周期。

ScheledThreadPoolExecutor會把待執行的任務放到工作隊列DelayQueue中,DelayQueue封裝了一個PriorityQueue,PriorityQueue會對隊列中的ScheledFutureTask進行排序,具體的排序比較演算法實現如下:

ScheledFutureTask在DelayQueue中被保存在一個PriorityQueue(基於數組實現的優先隊列,類似於堆排序中的優先隊列)中,在往數組中添加/移除元素時,會調用siftDown/siftUp來進行元素的重排序,保證元素的優先順序順序。

static class DelayedWorkQueue extends AbstractQueue<Runnable>
implements BlockingQueue<Runnable> {

private static final int INITIAL_CAPACITY = 16;
private RunnableScheledFuture<?>[] queue =
new RunnableScheledFuture<?>[INITIAL_CAPACITY];
private final ReentrantLock lock = new ReentrantLock();
private int size = 0;

private Thread leader = null;
private final Condition available = lock.newCondition();
}
從DelayQueue獲取任務的主要邏輯就在take()方法中,首先獲取lock,然後獲取queue[0],如果為null則await等待任務的來臨,如果非null查看任務是否到期,是的話就執行該任務,否則再次await等待。這里有一個leader變數,用來表示當前進行awaitNanos等待的線程,如果leader非null,表示已經有其他線程在進行awaitNanos等待,自己await等待,否則自己進行awaitNanos等待。

// DelayedWorkQueue
public RunnableScheledFuture<?> take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
for (;;) {
RunnableScheledFuture<?> first = queue[0];
if (first == null)
available.await();
else {
long delay = first.getDelay(NANOSECONDS);
if (delay <= 0)
return finishPoll(first);
first = null; // don't retain ref while waiting
if (leader != null)
available.await();
else {
Thread thisThread = Thread.currentThread();
leader = thisThread;
try {
available.awaitNanos(delay);
} finally {
if (leader == thisThread)
leader = null;
}
}
}
}
} finally {
if (leader == null && queue[0] != null)
available.signal();
lock.unlock();
}
}
獲取到任務之後,就會執行task的run()方法了,即ScheledFutureTask.run():

public void run() {
boolean periodic = isPeriodic();
if (!canRunInCurrentRunState(periodic))
cancel(false);
else if (!periodic)
ScheledFutureTask.super.run();
else if (ScheledFutureTask.super.runAndReset()) {
setNextRunTime();
reExecutePeriodic(outerTask);
}
}
推薦閱讀:
JMM Java內存模型
happens-before那些事兒
為什麼說LockSupport是Java並發的基石?
責任鏈的2種實現方式,你更pick哪一種
2閱讀

『肆』 java 用多線程測試資料庫連接池拋出異常

這不是很明顯嗎?
closeConnection(Connection connection)這個方法里無論如何都會把連接close掉,而連接池實際上應該只是釋放連接而並非直接把連接關掉。真正關掉連接的操作應該在關閉連接池的時候或者更為有效的連接管理策略中。

『伍』 連接池的好處

這種把連接「匯集」起來的技術基於這樣的一個事實:對於大多數應用程序,當它們正在處理通常需要數毫秒完成的事務時,僅需要能夠訪問JDBC連接的 1 個線程。當不處理事務時,這個連接就會閑置。相反,連接池允許閑置的連接被其它需要的線程使用。
事實上,當一個線程需要用 JDBC 對一個 GBase 或其它資料庫操作時,它從池中請求一個連接。當這個線程使用完了這個連接,將它返回到連接池中,這樣這就可以被其它想使用它的線程使用。
當連接從池中「借出」,它被請求它的線程專有地使用。從編程的角度來看,這和用戶的線程每當需要一個 JDBC 連接的時候調用DriverManager.getConnection() 是一樣的,採用連接池技術,可通過使用新的或已有的連接結束線程。
連接池可以極大的改善用戶的 Java 應用程序的性能,同時減少全部資源的使用。連接池主要的優點有:
減少連接創建時間
雖然與其它資料庫相比 GBase 提供了較為快速連接功能,但是創建新的 JDBC 連接仍會招致網路和 JDBC 驅動的開銷。如果這類連接是「循環」使用的,使用該方式這些花銷就可避免。
簡化的編程模式
當使用連接池時,每一個單獨的線程能夠像創建了一個自己的 JDBC 連接一樣操作,允許用戶直接使用JDBC編程技術。
受控的資源使用
如果用戶不使用連接池,而是每當線程需要時創建一個新的連接,那麼用戶的應用程序的資源使用會產生非常大的浪費並且可能會導致高負載下的異常發生。
注意,每個連到 GBase 的連接在客戶端和伺服器端都有花銷(內存,CPU,上下文切換等等)。每個連接均會對應用程序和 GBase 伺服器的可用資源帶來一定的限制。不管這些連接是否在做有用的工作,仍將使用這些資源中的相當一部分。
連接池能夠使性能最大化,同時還能將資源利用控制在一定的水平之下,如果超過該水平,應用程序將崩潰而不僅僅是變慢。

『陸』 java應用中可以有多少 線程池

可以有多少個線程池的問題,如果假設每個線程池中只有一個線程,那麼就轉化為應用中可以有多少個線程
這個跟jvm的配置,操作系統相關
每個線程在jvm中默認是分配1m大小的內存,當然可以調整,因此這個可用線程數的多少跟你操作系統目前剩餘內存有關
同時一個操作系統中最大的線程數一般為3000-5000,當然理論值是這樣,如果線程數過大,會有調度方面的延遲,導致大數量級的線程反而比小數量級的線程運行得更慢。

『柒』 Java線程池

java常用的線程池有三種:
1.
newFixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads)創建一個可重用固定線程數的線程池,以共享的無界隊列方式來運行這些線程。在任意點,在大多數 nThreads 線程會處於處理任務的活動狀態。如果在所有線程處於活動狀態時提交附加任務,則在有可用線程之前,附加任務將在隊列中等待。如果在關閉前的執行期間由於失敗而導致任何線程終止,那麼一個新線程將代替它執行後續的任務(如果需要)。在某個線程被顯式地關閉之前,池中的線程將一直存在。

參數:
nThreads - 池中的線程數
返回:
新創建的線程池
拋出:
IllegalArgumentException - 如果 nThreads <= 0

2.
newSingleThreadExecutor
public static ExecutorService newSingleThreadExecutor()創建一個使用單個 worker 線程的 Executor,以無界隊列方式來運行該線程。(注意,如果因為在關閉前的執行期間出現失敗而終止了此單個線程,那麼如果需要,一個新線程將代替它執行後續的任務)。可保證順序地執行各個任務,並且在任意給定的時間不會有多個線程是活動的。與其他等效的 newFixedThreadPool(1) 不同,可保證無需重新配置此方法所返回的執行程序即可使用其他的線程。

返回:
新創建的單線程 Executor

3.
newCachedThreadPool
public static ExecutorService newCachedThreadPool()創建一個可根據需要創建新線程的線程池,但是在以前構造的線程可用時將重用它們。對於執行很多短期非同步任務的程序而言,這些線程池通常可提高程序性能。調用 execute 將重用以前構造的線程(如果線程可用)。如果現有線程沒有可用的,則創建一個新線程並添加到池中。終止並從緩存中移除那些已有 60 秒鍾未被使用的線程。因此,長時間保持空閑的線程池不會使用任何資源。注意,可以使用 ThreadPoolExecutor 構造方法創建具有類似屬性但細節不同(例如超時參數)的線程池。

返回:
新創建的線程池

『捌』 在 Java 程序中怎麼保證多線程的運行安全

零基礎學習java可按照這份大綱來進行學習
第一階段:Java專業基礎課程
階段目標:
1. 熟練掌握Java的開發環境與編程核心知識
2. 熟練運用Java面向對象知識進行程序開發
3. 對Java的核心對象和組件有深入理解
4. 熟練應用JavaAPI相關知識
5. 熟練應用JAVA多線程技術
6. 能綜合運用所學知識完成一個項目
知識點:
1、基本數據類型,運算符,數組,掌握基本數據類型轉換,運算符,流程式控制制。
2、數組,排序演算法,Java常用API,類和對象,了解類與對象,熟悉常用API。
3、面向對象特性,集合框架,熟悉面向對象三大特性,熟練使用集合框架。
4、IO流,多線程。
5、網路協議,線程運用。
第二階段:JavaWEB核心課程
階段目標:
1. 熟練掌握資料庫和MySQL核心技術
2. 深入理解JDBC與DAO資料庫操作
3. 熟練運用JSP及Servlet技術完成網站後台開發
4. 深入理解緩存,連接池,註解,反射,泛型等知識
5. 能夠運用所學知識完成自定義框架
知識點:
1、資料庫知識,範式,MySQL配置,命令,建庫建表,數據的增刪改查,約束,視圖,存儲過程,函數,觸發器,事務,游標,建模工具。
2、深入理解資料庫管理系統通用知識及MySQL資料庫的使用與管理。為Java後台開發打下堅實基礎。Web頁面元素,布局,CSS樣式,盒模型,JavaScript,jQuery。
3、掌握前端開發技術,掌握jQuery。
4、Servlet,EL表達式,會話跟蹤技術,過濾器,FreeMarker。
5、掌握Servlet相關技術,利用Servlet,JSP相關應用技術和DAO完成B/S架構下的應用開發。
6、泛型,反射,註解。
7、掌握JAVA高級應用,利用泛型,註解,枚舉完成自己的CRUD框架開發為後續框架學習做鋪墊。
8、單點登錄,支付功能,項目整合,分頁封裝熟練運用JSP及Servlet核心知識完成項目實戰。
第三階段:JavaEE框架課程
階段目標:
1. 熟練運用Linux操作系統常見命令及完成環境部署和Nginx伺服器的配置
2. 熟練運用JavaEE三大核心框架:Spring,SpringMVC,MyBatis
3. 熟練運用Maven,並使用SpringBoot進行快速框架搭建
4. 深入理解框架的實現原理,Java底層技術,企業級應用等
5. 使用Shiro,Ztree和Spring,SpringMVC,Myts完成企業項目
知識點:
1、Linux安裝配置,文件目錄操作,VI命令,管理,用戶與許可權,環境部署,Struts2概述,hiberante概述。
2、Linux作為一個主流的伺服器操作系統,是每一個開發工程師必須掌握的重點技術,並且能夠熟練運用。
3、SSH的整合,MyBatis,SpringMVC,Maven的使用。
4、了解AOP原理,了解中央控制器原理,掌握MyBatis框架,掌握SSM框架的整合。
5、Shiro,Ztree,項目文檔,項目規范,需求分析,原型圖設計,資料庫設計,工程構建,需求評審,配置管理,BUG修復,項目管理等。
6、獨立自主完成一個中小型的企業級綜合項目的設計和整體架構的原型和建模。獨立自主完成一個大型的企業級綜合項目,並具備商業價值

『玖』 請寫一個java程序實現線程連接池功能

方法一:繼承 Thread 類,覆蓋方法 run(),我們在創建的 Thread 類的子類中重寫 run() ,加入線程所要執行的代碼即可。下面是一個例子:

public class MyThread extends Thread {

int count= 1, number;

public MyThread(int num) {

number = num;

System.out.println("創建線程 " + number);

}

public void run() {

while(true) {

System.out.println("線程 " + number + ":計數 " + count);

if(++count== 6) return;

}

}

public static void main(String args[]) {

for(int i = 0; i 〈 5; i++) new MyThread(i+1).start();

}

}

閱讀全文

與java線程池連接池相關的資料

熱點內容
加密歐美航線 瀏覽:48
svn怎麼看伺服器的地址 瀏覽:187
騎馬與砍殺1命令部隊用盾牌 瀏覽:595
光纜pdf 瀏覽:350
加密流量實時監測 瀏覽:628
360壓縮和好壓哪個好 瀏覽:61
python判斷變數是否為list 瀏覽:906
雲伺服器1m帶寬表示什麼意思 瀏覽:702
429升冷櫃用多大壓縮機 瀏覽:116
決策樹演算法java實現 瀏覽:376
androidtv開發焦點控制 瀏覽:328
論人的成長pdf 瀏覽:282
python網站源代碼 瀏覽:827
手機文件壓縮器怎麼安裝 瀏覽:112
androidsdk封裝 瀏覽:266
微信加密不知道怎麼取消 瀏覽:705
分析演算法設計程序編寫 瀏覽:843
linux啟動dhcp失敗 瀏覽:356
芙蓉出水選股公式源碼 瀏覽:763
linux更改密碼錯誤 瀏覽:244