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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

数据库连接池-连接的关闭内幕

發(fā)布時(shí)間:2024/4/14 数据库 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据库连接池-连接的关闭内幕 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
們經(jīng)常會(huì)遇到這樣那樣的連接未關(guān)閉的問題,連接沒有及時(shí)關(guān)閉導(dǎo)致的直接后果就是內(nèi)存泄漏直至down機(jī)。我們也都知道解決的方式,但是在解決了問題之后經(jīng)常會(huì)思考為什么會(huì)這樣呢?連接close()掉,然后在創(chuàng)建不是很浪費(fèi)cpu等系統(tǒng)資源嘛?有沒有更好的方法解決呢?大家也經(jīng)常聽到連接池、線程池之類的線程、池的概念,那么究竟這些概念與我們的連接有什么關(guān)系呢?

???????下面我就想就上面的問題談?wù)勎业囊稽c(diǎn)淺見,請大家批評(píng)指正。

???????大家都知道java語言是一種語言級(jí)的多線程機(jī)制的面向?qū)ο笳Z言。比如說,java的基類object,它就有一些諸如wati(),notify(),notifyall()等線程控制的方法。如果大家學(xué)習(xí)過操作系統(tǒng)的化,我想應(yīng)該知道線程存在同步和異步的問題,解決的方法很多,其中就有“信號(hào)量機(jī)制”實(shí)現(xiàn)線程的同步,java的這種同步機(jī)制與操作系統(tǒng)大同小異。同步機(jī)制是一個(gè)比較復(fù)雜的問題,如果感興趣可以找一本操作系統(tǒng)的書看看。

???????下面簡單介紹一些進(jìn)程和線程的概念:

1.?????????進(jìn)程:

???????進(jìn)程是資源分配和獨(dú)立運(yùn)行的基本單位。進(jìn)程的定義很多,下面列舉一些

??????????進(jìn)程是程序的一次執(zhí)行;

??????????進(jìn)程是可以和別的計(jì)算機(jī)并發(fā)執(zhí)行的計(jì)算;

??????????進(jìn)程可定義為一個(gè)數(shù)據(jù)結(jié)構(gòu)及能在其上進(jìn)行操作的一個(gè)程序

??????????進(jìn)程是一個(gè)程序及其數(shù)據(jù)在處理機(jī)上順序執(zhí)行時(shí)發(fā)生的活動(dòng);

??????????進(jìn)程時(shí)程序在一個(gè)數(shù)據(jù)集合上的運(yùn)行過程,時(shí)系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位。

2.?????????線程

由于進(jìn)程是一個(gè)資源擁有者,因而在進(jìn)程的創(chuàng)建、撤消和切換過程中,系統(tǒng)必須為之付出較大的時(shí)空開銷。也正因?yàn)槿绱?#xff0c;在系統(tǒng)中所設(shè)置的進(jìn)程數(shù)目不宜過多,進(jìn)程切換的頻率也不宜過高,但這也就限制了并發(fā)程度的進(jìn)一步提高。因此便引出了線程的概念

把線程作為調(diào)度和分派的基本單位,而把進(jìn)程作為資源擁有的基本單位,使傳統(tǒng)進(jìn)程的兩個(gè)屬性分開,線程便能輕裝運(yùn)行,從而顯著提高系統(tǒng)的并發(fā)程度。

??????????在同一個(gè)進(jìn)程內(nèi)可以有多個(gè)線程;

??????????同一個(gè)進(jìn)程內(nèi)的線程切換不會(huì)引起進(jìn)程切換;

??????????一個(gè)進(jìn)程的線程切換到另一個(gè)進(jìn)程的線程時(shí)會(huì)引起進(jìn)程切換

3.?????????JSP/SERVLET

而我們常用的jsp/ervlet這種j2ee的體系結(jié)構(gòu)正是建立在java的多線程機(jī)制之上的。JSP/SERVLET容器會(huì)自動(dòng)使用線程池等技術(shù)來支持系統(tǒng)的運(yùn)行。因此,JSP/SERVLET的實(shí)質(zhì)是一種線程技術(shù),JSP會(huì)在運(yùn)行時(shí)被編譯成servlet來運(yùn)行,如圖所示:

???????當(dāng)客戶端向服務(wù)器發(fā)出一個(gè)請求時(shí),servlet容器會(huì)分配一個(gè)線程專門處理這個(gè)請求,線程內(nèi)容就是JSP/servlet應(yīng)用程序。

???????這部分內(nèi)容與本主體無關(guān),只是順便說說。

4.?????????線程池

???????首先介紹一下線程池:

???????線程的創(chuàng)建和銷毀,以及切換,執(zhí)行都是要耗費(fèi)系統(tǒng)資源的。當(dāng)系統(tǒng)訪問量比較大的時(shí)候,服務(wù)器內(nèi)就會(huì)創(chuàng)建太多的線程,直至資源完全消耗,這對于應(yīng)用系統(tǒng)的正常運(yùn)行是有致命傷害的。

???????為了能夠在訪問尖峰時(shí)限制活動(dòng)線程的數(shù)量,同時(shí)減少線程頻繁創(chuàng)建和銷毀帶來的系統(tǒng)開銷,提高系統(tǒng)的大訪問量的處理性能和速度,需要事先創(chuàng)建一定數(shù)量的線程供調(diào)用者循環(huán)反復(fù)使用,這就是“池”技術(shù)。

???????線程的基本原理是基于隊(duì)列queue這種數(shù)據(jù)結(jié)構(gòu)的,通過不斷查詢隊(duì)列queue是否有可以運(yùn)行的線程。如果有,就立即運(yùn)行線程,沒有,則鎖定等待,直到有新的線程加入被解鎖。(這種鎖定機(jī)制,就是所謂的“信號(hào)量機(jī)制”)。

???????一種線程池必須解決如下的問題:死鎖、資源不足、并發(fā)錯(cuò)誤、線程泄漏和請求過載。下面我們具體舉一個(gè)成熟的開源線程池的例子來說明線程池的原理:

????PooledExecutor?pool=new?PooledExecutor(new?BoundedBuffer(20),100);

????pool.setMinimumPoolSize(10);//最小線程數(shù)為10

????poole.setKeepAliveTime(-1);//線程一直運(yùn)行

????上面的語句設(shè)置了線程的最大數(shù)目為100,這樣,就可以保護(hù)系統(tǒng)不會(huì)因?yàn)樵L問量增加導(dǎo)致線程數(shù)目的無限增加。使用該線程池如下:

???????pool.execute(java.lang.Runnable?自己的線程);

???????這一句實(shí)際上是將“自己的線程”加入一個(gè)隊(duì)列中,而隊(duì)列(先進(jìn)先出FIFO)另一段正開啟多個(gè)線程不斷讀取這個(gè)隊(duì)列,一旦隊(duì)列中有空閑的線程,線程管理器就將讀取并分配線程來運(yùn)行它。

? ? ??

????public?void?execute(Runnable?command)?throws?InterruptedException?{

???????for?(;;)?{?//一直循環(huán)

???????????synchronized?(this)?{

??????????????if?(!shutdown_)?{?//確保線程池沒有關(guān)閉

??????????????????int?size?=?poolSize_;?//當(dāng)前線程池中線程的數(shù)目

??????????????????if?(size?<?minimumPoolSize_)?{?//如果當(dāng)前線程數(shù)目少于線程池最小數(shù)目

?????????????????????addThread(command);

?????????????????????return;

??????????????????}

??????????????????//如果目前線程池中有超過或等于最小數(shù)目的線程

??????????????????//分配一個(gè)存在的空閑線程來運(yùn)行commandhandOff是隊(duì)列

??????????????????if?(handOff_.offer(command,?0))?{

?????????????????????return;

??????????????????}

??????????????????//如果不能分配已有的線程來運(yùn)行command,那么創(chuàng)建一個(gè)新線程

??????????????????if?(size?<?maximumPoolSize_)?{

?????????????????????addThread(command);

?????????????????????return;

??????????????????}

??????????????}

???????????}

???????????//如果阻塞,則請求幫助

???????????if?(getBlockedExecutionHandler().bolckedAction(command))?{

??????????????return;

???????????}

???????}

????}

???????由上面的代碼可見,PooledExecutor線程池的原理是,當(dāng)執(zhí)行execute加載一個(gè)應(yīng)用系統(tǒng)的線程時(shí),線程池內(nèi)部首先檢查當(dāng)前線程數(shù)目是否達(dá)到設(shè)定的最小數(shù)目。如果沒有達(dá)到,啟動(dòng)新線程運(yùn)行;如果達(dá)到了,那么檢查有無空閑線程可用;如果沒有空閑的,則創(chuàng)建新線程,直到達(dá)到最大數(shù)目。

???????使用線程池的好處是:首先是循環(huán)使用,一經(jīng)創(chuàng)建后,空閑的線程可以被反復(fù)使用,提高了運(yùn)行效率;其次有最大數(shù)目的限制,保證了系統(tǒng)的安全性。

5.?????????連接池

終于輪到連接池了,通過上面的介紹,我們對線程及線程池都有個(gè)一個(gè)大致的了解。

在正常情況下,直接使用JDBC調(diào)用數(shù)據(jù)庫可以滿足一個(gè)小型系統(tǒng)的要求,但是當(dāng)系統(tǒng)規(guī)模比較大的情況下,就會(huì)出現(xiàn)數(shù)據(jù)庫的訪問量迅速提升而令服務(wù)器不堪重負(fù)的現(xiàn)象,因而為了解決這一性能問題,常常會(huì)使用數(shù)據(jù)庫連接池作為一個(gè)緩存的方式解決。

連接池類似上面介紹的線程池。

每次數(shù)據(jù)庫連接的建立都需要花費(fèi)一定的時(shí)空費(fèi)用,而使用連接池,可以事先建立連接。當(dāng)應(yīng)用程序需要開始使用時(shí),就從連接池中獲取一個(gè)連接使用,應(yīng)用程序使用完畢,通過close()方法將連接歸還連接池。講到這里,我門就不必在擔(dān)心close()方法會(huì)不會(huì)影響性能了,完全可以放心大膽的使用。因?yàn)?#xff0c;它實(shí)際上并沒有關(guān)閉連接,而是將連接歸還連接池,供下次使用

當(dāng)并發(fā)增加是,連接池會(huì)不斷的自動(dòng)創(chuàng)建新的連接滿足調(diào)用,直到達(dá)到連接池的最大數(shù)目;當(dāng)連接池連接減少甚至沒有時(shí),連接池自動(dòng)關(guān)閉一些連接,保持最小數(shù)目。

因此連接池的使用節(jié)省了連接建立時(shí)間,消除了數(shù)據(jù)庫頻繁連接帶來的開銷和瓶頸。

小提示:不知道大家有沒有注意到配置websphere時(shí)有關(guān)于連接池最大最小數(shù)目的配置。呵呵,道理就在這。

那么,我們經(jīng)常面對的連接未關(guān)閉的問題導(dǎo)致的系統(tǒng)速度很慢的問題就很容易說明了,就是因?yàn)榫€程池已經(jīng)達(dá)到了最大數(shù)目,沒有可用的了。所以,其他操作只有等待的份,等待那些應(yīng)用用完了,被垃圾回收了,才能釋放出可用的連接。?

總結(jié)

以上是生活随笔為你收集整理的数据库连接池-连接的关闭内幕的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。