java虛擬機(jī)中多線程是怎樣總結(jié)的

本篇文章為大家展示了java虛擬機(jī)中多線程是怎樣總結(jié)的,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

創(chuàng)新互聯(lián)建站是專業(yè)的山西網(wǎng)站建設(shè)公司,山西接單;提供成都網(wǎng)站建設(shè)、成都做網(wǎng)站,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行山西網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊,希望更多企業(yè)前來合作!

我記得最開始接觸多進(jìn)程,多線程這一塊的時候我不是怎么理解,為什么要有多線程???多線程到底是個什么鬼啊?我一個程序好好的就可以運行為什么要用到多線程啊?反正我是十分費解,即使過了很長時間我還是不是很懂,聽別人說過也自己試過,但總是沒有理解透徹;

時間過了很久感覺現(xiàn)在對多線程有了一點新的理解,我們還是從最基本的開始,順便看看從jvm的角度看看多線程在jvm中是怎么分配內(nèi)存的,順便和前面的幾篇內(nèi)容串一下;

1.現(xiàn)實中的多線程

舉個例子:假如你一個人在家,你現(xiàn)在聽首歌5分鐘,燒開水需要10分鐘,玩一局游戲要20分鐘,現(xiàn)在問題來了,你完成這三件事總共需要多少分鐘?

假如是小學(xué)生肯定會回答5+10+20=35分鐘啊,但我們比小學(xué)生牛一點,稍微思考一下就知道是20分鐘,因為三件事可以同時做嘛,玩游戲的同時可以聽歌,順便燒開水,一把游戲打完,歌聽完了,水也燒開然后可以去泡茶了,舒服!

我們用一個比較簡陋的圖看看這兩種方式(這里先不考慮并發(fā)與并行的區(qū)別,方便理解)

可以粗略的看到如果是小學(xué)生的話,要一件事一件事的做,最后花的時間是三者時間總和;而我們比較聰明,由于三件事互不影響,我們可以三件事同時開始做,這樣就大大減少了不必要的等待時間,最終三者花費的時間差不多就是最長的那一個。

這里稍微提一下并發(fā)和并行的區(qū)別;

并發(fā):這個是在計算機(jī)單核CPU的前提之下,我們要清楚一個CPU在某一時刻只能做一件事,但是現(xiàn)在有三件事(聽歌,燒開水,玩游戲)交給CPU做,CPU是個好人,任勞任怨,一下子去聽歌,一下子去燒開水,一下子玩游戲,最終可以把三件事都給做完,但是假如同時有幾百件事交給CPU做呢?emmmm,最后CPU就被累垮了,住院去了,于是我們計算機(jī)也卡死了;舉個最貼近我們的例子:以前上學(xué)的時候作業(yè)太多,很多時候都是很多科目的作業(yè)都沒有做完,那怎么辦呢?只有早上去早點去抄一下同學(xué)的,但是各個課代表來收作業(yè)了,于是只能這個科目作業(yè)抄一點馬上又把另外一個科目作業(yè)抄一點,瑪?shù)拢詈蠼K于在規(guī)定時間都抄完了,可是假如你有100個科目的作業(yè)沒做完,你會怎么辦?用命去抄也抄不完了,于是你就累病了。。。。

并行:多核CPU的前提,現(xiàn)在一個電腦都有多個CPU,那么CPU同時就可以做多件事,即使事情再多,多個CPU進(jìn)行切換最終花費的時間確實大大減少;還是說說上面抄作業(yè)的例子,假如你現(xiàn)在有10門科目的作業(yè)沒做完,就靠你一個頭腦一只手肯定來不及??!于是這個時候你喚醒了前世的記憶,原來你是哪吒轉(zhuǎn)世,特么的居然可以變成是三頭六臂,這得可以同時抄多少份作業(yè)?。。?!一下子作業(yè)就做完了,舒服!但是這個時候作業(yè)科目太多的話你即使有三頭六臂也不夠用啊,而且相互之間的協(xié)調(diào)也就變成一個很重要的問題。

并發(fā)和并行就是這個意思,我們現(xiàn)在只關(guān)注并發(fā),看看在單核CPU的計算機(jī)中一個程序是怎么運行的?

2.進(jìn)程和線程

想想什么叫做進(jìn)程呢?我的理解就是程序進(jìn)入了內(nèi)存就是進(jìn)程,比如我們電腦桌面雙擊QQ,優(yōu)酷,java虛擬機(jī)等,操作系統(tǒng)就會把這些軟件的內(nèi)容加載到內(nèi)存中去運行去了,然后就是運行某編程語言寫的代碼,轉(zhuǎn)化為機(jī)器碼調(diào)用操作系統(tǒng)的接口,然后操作系統(tǒng)的內(nèi)核會那些硬件驅(qū)動程序發(fā)出一些指令,然后我們的電腦屏幕就出現(xiàn)變化了。。。我們簡單畫一畫圖,我們主要看JVM

我們再進(jìn)入JVM中看看,其中線程1、2、3就是我們在java代碼中要去實現(xiàn)的;

進(jìn)程:我們百度一下進(jìn)程的定義,最重要的一點就是進(jìn)程是操作系統(tǒng)資源分配的基本單位,因為每啟動一個程序,一個進(jìn)程就創(chuàng)建了,在操作系統(tǒng)堆內(nèi)存空間上就開辟了一塊空間,也就是分配了資源。

線程:現(xiàn)在再來看線程,百度一下線程定義,其實就是說:進(jìn)程就是一個程序,這個程序之中可能會同時執(zhí)行多個任務(wù)的代碼,每一個任務(wù)就是一個線程,而且每一個線程都會在JVM中有自己獨立的java棧,pc寄存器,而且CPU只能切換線程,即使是不同程序的線程也可以相互切換。

這里就要說明一下,想比進(jìn)程和線程,創(chuàng)建一個進(jìn)程是要在操作系統(tǒng)內(nèi)存中去開辟空間,會涉及到對操作系統(tǒng)一些函數(shù)的調(diào)用,而創(chuàng)建一個線程(比如在JVM中)只需要在jvm中個部分開辟空間,相比較之下,肯定是創(chuàng)建線程所耗費的操作系統(tǒng)資源比較少,但是也不可能無限制的創(chuàng)建很多線程,不然jvm也會出問題!

我隨便查了一下,一般的web服務(wù)器線程數(shù)最大不能超過CPU核數(shù)*50,如:8核<300,16核<800,根據(jù)實際情況還可以適當(dāng)調(diào)一下。

記得有句話叫做多個線程之間會競爭CPU資源這句話當(dāng)初我可是很久都沒有理解,這競爭CPU資源到底什么鬼?CPU的資源到底是什么???emmmm..

記得以前家里比較窮,沒有像現(xiàn)在一樣手機(jī)電腦這么多,家里只有一個電視!但是有的時候家里人每個人喜歡看的節(jié)目都不一樣,于是不可避免的相互之間就為了爭這個遙控器而發(fā)生沖突,哈哈哈!這個時候遙控器就相當(dāng)于CPU,我們每個人都相當(dāng)于一個線程要完成自己的事情。但是遙控器就一個,就會相互搶遙控器,有的時候我搶過來遙控器看火影忍者沒到一分鐘,就被我姐搶去看美食節(jié)目,沒過一會兒遙控器就被我爸搶去看新聞去了。。。。。

3.java中的多線程用法

java之中用多線程主要是3種方式:類,接口,線程池,接下來我們就隨意看一下這三種方式

3.1.類

這種方式主要是繼承Thread類,實現(xiàn)run()方法,run()方法就是我們所需要做的任務(wù)的邏輯代碼,然后將這個類實例化調(diào)用start()方法,表示現(xiàn)在這個線程隨時可以被CPU調(diào)用;

我還是以上面玩游戲,燒開水和聽歌為例,隨意寫個小例子:

注意:這里先不看GC,前臺線程有四個線程,我們創(chuàng)建的三個,還有執(zhí)行main方法的這個線程(這個也叫主線程),我們只能保證主線程最優(yōu)先運行,至于這四個線程哪個先停止,隨機(jī)。。。

3.2.接口

這種方式也差不多,實現(xiàn)Runnable接口,實現(xiàn)其中的run()方法,然后實例化這個對象并傳入Thread類中,再調(diào)用start()方法;

3.3.線程池

什么是線程池呢?你看看我們上面寫的創(chuàng)建線程的方法,都是用的時候就去創(chuàng)建,用完了就銷毀,下次又要用就又去創(chuàng)建,這種做法很不好,因為每次創(chuàng)建和銷毀線程都是很消耗jvm內(nèi)部資源的,因為在jvm內(nèi)部會進(jìn)行申請空間,分配空間和釋放空間各種操作,對jvm的性能會有一定的影響,而且假如某個特殊的情況下每個線程只會運行很短的時間就會結(jié)束,那么就會十分頻繁的常見和銷毀線程,導(dǎo)致在jvm中頻繁的申請和釋放內(nèi)存,這極大的影響jvm的運行性能。

但是啊,如果我們能在程序啟動的時候,就先創(chuàng)建一定數(shù)量的線程放在一個池子里,我們要用的話就去拿,用完了就再放到池子里,這樣就很好的避免了創(chuàng)建和銷毀線程的過程,這種方式比較友好;其中這個存放線程的池子就叫做線程池,接下來我們隨意看看線程池的用法:

順便一提,利用線程池執(zhí)行線程任務(wù)有兩種方式,一種是我們用的pool.execute(xxxx),另外一種是pool.submit(xxxx),用法和參數(shù)都一樣,區(qū)別是用submit()提交內(nèi)部其實還是調(diào)用execute(),而且還可以獲取線程執(zhí)行后的返回值,后面我們會分析到的;

線程池起到一個類似緩沖的作用,它可以對池子中的線程數(shù)目進(jìn)行控制,想想,假如我們程序直接創(chuàng)建線程那可能會由于創(chuàng)建線程太多導(dǎo)致jvm崩潰,但是我們有一個確定容量的池子,我們不用擔(dān)心這個池子會炸了,我們只需要從池子里拿就好了,至于拿不拿得到的問題后面我們會好好分析的;

3.4.看看Callable接口

這個接口干嘛的呢?有了Runnable接口了,還要這個接口干嘛?

不知道有沒有注意到那個Runnable接口的run()方法是沒有返回值的,也就是說我們只能把任務(wù)交給這個線程去做,但是做了之后有沒有成功,線程是否異常我們都是不知道的,于是才有了Callable接口,這個接口就是對Runnable接口的一個補充,這個接口的實現(xiàn)類中沒有run()方法,卻有一個call()方法用于執(zhí)行我們的任務(wù)邏輯,而且還能有返回值,并且能拋出異常等

順便一提,返回值已經(jīng)被封裝成一個Future<T>類型的了,我們只需要從這個Futrue中取到返回值就可以進(jìn)行后續(xù)操作了,有興趣的可以看看Futrue這個包裝類中有哪些方法可以試試,反正我暫時是沒什么興趣的。。。。

4.多線程下的jvm內(nèi)存結(jié)構(gòu)

初學(xué)者學(xué)多線程其實最迷糊的一點就是多線程的程序中,jvm是什么樣的啊?還是向以前那樣分嗎?到底多線程這個東西在jvm中是怎么樣存在的呢?下面我們就來簡單看看;

我自己總結(jié)的一句話:一個線程一個棧,一個方法一個幀;

這句話的意思就是每創(chuàng)建一個線程就會創(chuàng)建一個棧,每調(diào)用一個方法就會在棧中壓入一個棧幀;

其實java棧是一個動態(tài)的東西,不像我們前面看jvm內(nèi)存結(jié)構(gòu)就是一大塊java棧,里面可以有很多塊,一個線程一塊,總共合起來叫做java棧,我繼續(xù)來畫一個丑陋的圖看一看:

其實可以看到在我們java程序中用多線程的話,那么每一個線程都會創(chuàng)建一個棧,同時每個線程都有自己的PC計數(shù)器,而且每個棧都是該線程私有的,別的線程不能訪問;但是在java堆和方法區(qū)中的數(shù)據(jù),是所有線程共享的,由于所有的線程都能夠使用共享區(qū)的數(shù)據(jù),假設(shè)一個線程拿到堆中的一個A對象進(jìn)行修改但是需要的時間比較長,此時另一個線程也要拿到A對象進(jìn)行判斷然后做一些操作,這個時候就會出問題,因為前一個線程修改的數(shù)據(jù)還沒有同步過來,后面線程拿到的是舊數(shù)據(jù),這個問題就是多線程的同步問題,后面我們慢慢分析;

5.總結(jié)

其實初學(xué)者覺得多線程比較難,主要是因為不理解多線程到底是什么?我們可以把多線程代碼用這種奇葩的形式看是不是明顯多了,其中主線程最開始執(zhí)行并創(chuàng)建自己的棧和PC計數(shù)器,一直到創(chuàng)建其他的三個線程并把分別調(diào)用start()方法的時候,這些線程會隨機(jī)由CPU執(zhí)行以及切換線程,并且各個線程都會創(chuàng)建自己的棧和PC計數(shù)器;而堆和方法區(qū)的數(shù)據(jù)是共享的,這會導(dǎo)致出現(xiàn)線程同步問題;

注意:千萬不要覺得主線程比其他創(chuàng)建的線程要特殊,除了我們程序是由主線程開始之外,這些線程都是出于同一地位,很有可能首先是主線程執(zhí)行完畢,然后再執(zhí)行1、2、3這三個線程哦~~

上述內(nèi)容就是java虛擬機(jī)中多線程是怎樣總結(jié)的,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

名稱欄目:java虛擬機(jī)中多線程是怎樣總結(jié)的
當(dāng)前路徑:http://bm7419.com/article24/gipoje.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計Google品牌網(wǎng)站建設(shè)、微信小程序虛擬主機(jī)、網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作