亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        基于Java多線程同步的安全性研究

        2011-03-17 01:43:42張勇
        關(guān)鍵詞:副本盤子線程

        張勇

        (宿州職業(yè)技術(shù)學(xué)院計算機(jī)信息系,安徽宿州234101)

        Java多線程是提高程序效能的利器,對于如何開發(fā)多線程的程序,已經(jīng)有了很多的研究。本文并不是告訴您如何編寫多線程Java程序,而著重于研究多線程的并發(fā)控制以及如何描述線程執(zhí)行的過程,線程運(yùn)行的機(jī)制,線程同步的必要性,和線程同步的解決方法。因?yàn)橹挥型耆瓶豃ava多線程執(zhí)行的過程,明白線程運(yùn)行的機(jī)制,才能開發(fā)出高安全性的Java應(yīng)用程序。

        1 統(tǒng)一的Java內(nèi)存模型規(guī)范

        不同的平臺,內(nèi)存模型是不一樣的,但是JVM的內(nèi)存模型規(guī)范是統(tǒng)一的。其實(shí)Java的多線程并發(fā)問題最終都會反映在Java的內(nèi)存模型上,所謂線程安全無非是要控制多個線程對某個資源的有序訪問或修改。其實(shí)Java的內(nèi)存模型就是要解決兩個主要的問題:可見性和有序性。我們都知道計算機(jī)有高速緩存的存在,處理器并不是每次處理數(shù)據(jù)都是取內(nèi)存的。JVM定義了自己的內(nèi)存模型,屏蔽了底層平臺內(nèi)存管理細(xì)節(jié),對于Java開發(fā)人員,要清楚在JVM內(nèi)存模型的基礎(chǔ)上如何解決多線程的可見性和有序性[1]。

        在JAVA程序的執(zhí)行過程中,線程不能直接為主存中的字段賦值,它會將值指定給工作內(nèi)存中的變量副本(assign),完成后這個變量副本會同步到主存儲區(qū)(store-write),至于何時同步到主存,根據(jù)JVM實(shí)現(xiàn)系統(tǒng)決定。有些字段,則會從主內(nèi)存中將該字段賦值到工作內(nèi)存中,這個過程為read -load,完成后線程會引用該變量副本,當(dāng)同一線程多次重復(fù)對字段賦值時,如

        線程有可能只對工作內(nèi)存中的副本進(jìn)行賦值,直到最后一次賦值后才同步到主存儲區(qū),所以assign,store,weite順序可以由JVM實(shí)現(xiàn)系統(tǒng)決定。

        假設(shè)有一個共享變量x,線程A執(zhí)行x=x+ 1。從上面的描述中可以知道x=x+1并不是一個原子操作,它的執(zhí)行過程如下:從主存中讀取變量x副本到工作內(nèi)存→給x加1→將x加1后的值寫回主存,如果另外一個線程B執(zhí)行x=x-1,執(zhí)行過程如下:從主存中讀取變量 x副本到工作內(nèi)存→給x減1→將 x減1后的值寫回主存。那么顯然,最終的 x的值是不可靠的。假設(shè) x現(xiàn)在為10,線程A加1,線程B減1,從表面上看,似乎最終x還是為10,但是多線程情況下會有這種情況發(fā)生:

        1)線程 A從主存讀取x副本到工作內(nèi)存,工作內(nèi)存中x值為10。

        2)線程B從主存讀取x副本到工作內(nèi)存,工作內(nèi)存中x值為10。

        3)線程A將工作內(nèi)存中x加1,工作內(nèi)存中 x值為11。

        4)線程A將x提交主存中,主存中x為11。

        5)線程B將工作內(nèi)存中x值減1,工作內(nèi)存中x值為9。

        6)線程B將x提交到中主存中,主存中x為9。

        同樣x有可能為11,如果x是一個銀行賬戶,線程A存款,線程 B扣款,顯然這樣是有嚴(yán)重問題的,要解決這個問題,必須保證線程A和線程B是有序執(zhí)行的,并且每個線程執(zhí)行的加1或減1是一個原子操作。

        2 Synchronized關(guān)鍵字的使用

        上面說了,Java用synchronized關(guān)鍵字做為多線程并發(fā)環(huán)境的執(zhí)行有序性的保證手段之一。當(dāng)一段代碼會修改共享變量,這一段代碼成為互斥區(qū)或臨界區(qū),為了保證共享變量的正確性,synchronized標(biāo)示了臨界區(qū)。典型的用法如下:

        為了保證銀行賬戶的安全,可以操作賬戶的方法如下:

        那么對于public synchronized void add(int num)這種情況,意味著什么呢?其實(shí)這種情況,鎖就是這個方法所在的對象。同理,如果方法是public static synchronized void add(int num),那么鎖就是這個方法所在的class。理論上,每個對象都可以做為鎖,但一個對象做為鎖時,應(yīng)該被多個線程共享,這樣才顯得有意義,在并發(fā)環(huán)境下,一個沒有共享的對象作為鎖是沒有意義的。

        每個鎖對象都有兩個隊列,一個是就緒隊列,一個是阻塞隊列,就緒隊列存儲了將要獲得鎖的線程,阻塞隊列存儲了被阻塞的線程,當(dāng)一個線程被喚醒(notify)后,才會進(jìn)入到就緒隊列,等待cpu的調(diào)度。當(dāng)一開始線程A第一次執(zhí)行account.add方法時,JVM會檢查鎖對象account的就緒隊列是否已經(jīng)有線程在等待,如果有則表明account的鎖已經(jīng)被占用了,由于是第一次運(yùn)行,account的就緒隊列為空,所以線程A獲得了鎖,執(zhí)行account.add方法。如果恰好在這個時候,線程b要執(zhí)行account.withdraw方法,因?yàn)榫€程 A已經(jīng)獲得了鎖還沒有釋放,所以線程 B要進(jìn)入account的就緒隊列,等到得到鎖后才可以執(zhí)行。

        一個線程執(zhí)行臨界區(qū)代碼過程如下:獲得同步鎖→清空工作內(nèi)存→從主存拷貝變量副本到工作內(nèi)存→對這些變量計算→將變量從工作內(nèi)存寫回到主存→釋放鎖,可見,synchronized既保證了多線程的并發(fā)有序性,又保證了多線程的內(nèi)存可見性[3]。

        3 模式問題的解決

        生產(chǎn)者/消費(fèi)者模式其實(shí)是一種很經(jīng)典的線程同步模型,很多時候,并不是光保證多個線程對某共享資源操作的互斥性就夠了,往往多個線程之間都是有協(xié)作的。

        假設(shè)有這樣一種情況,有一個桌子,桌子上面有一個盤子,盤子里只能放一顆雞蛋,A專門往盤子里放雞蛋,如果盤子里有雞蛋,則一直等到盤子里沒雞蛋,B專門從盤子里拿雞蛋,如果盤子里沒雞蛋,則等待直到盤子里有雞蛋。其實(shí)盤子就是一個互斥區(qū),每次往盤子放雞蛋應(yīng)該都是互斥的, A的等待其實(shí)就是主動放棄鎖,B等待時還要提醒A放雞蛋。

        如何讓線程主動釋放鎖,很簡單,調(diào)用鎖的wait()方法就好。wait()方法是從Object來的,所以任意對象都有這個方法。

        如果一個線程獲得了鎖lock,進(jìn)入了同步塊,執(zhí)行l(wèi)ock.wait(),那么這個線程會進(jìn)入到lock的阻塞隊列。如果調(diào)用lock.notify()則會通知阻塞隊列的某個線程進(jìn)入就緒隊列。

        聲明一個盤子,只能放一個雞蛋。

        聲明一個Plate對象為plate,被線程A和線程B共享,A專門放雞蛋,B專門拿雞蛋。

        假設(shè)(1)開始,A調(diào)用plate.putEgg方法,此時eggs.size()為0,因此順利將雞蛋放到盤子,還執(zhí)行了notify()方法,喚醒鎖的阻塞隊列的線程,此時阻塞隊列還沒有線程。(2)又有一個A線程對象調(diào)用plate.putEgg方法,此時eggs.size()不為0,調(diào)用wait()方法,自己進(jìn)入了鎖對象的阻塞隊列。(3)此時,來了一個B線程對象,調(diào)用plate.getEgg方法,eggs.size()不為0,順利的拿到了一個雞蛋,還執(zhí)行了notify()方法,喚醒鎖的阻塞隊列的線程,此時阻塞隊列有一個A線程對象,喚醒后,它進(jìn)入到就緒隊列,就緒隊列也就它一個,因此馬上得到鎖,開始往盤子里放雞蛋,此時盤子是空的,因此放雞蛋成功。(4)假設(shè)接著來了線程A,就重復(fù)2;假設(shè)來料線程B,就重復(fù)3。整個過程都保證了放雞蛋,拿雞蛋,放雞蛋,拿雞蛋。

        4 volatile關(guān)鍵字的使用場景

        volatile是Java提供的一種同步手段,只不過它是輕量級的同步,為什么這么說,因?yàn)関olatile只能保證多線程的內(nèi)存可見性,不能保證多線程的執(zhí)行有序性。而最徹底的同步要保證有序性和可見性,例如synchronized。任何被volatile修飾的變量,都不拷貝副本到工作內(nèi)存,任何修改都及時寫在主存。因此對于valatile修飾的變量的修改,所有線程馬上就能看到,但是volatile不能保證對變量的修改是有序的[4]。假如:

        當(dāng)一個VolatileTest對象被多個線程共享,a的值不一定是正確的,因?yàn)閍=a+count包含了好幾步操作,而此時多個線程的執(zhí)行是無序的,因?yàn)闆]有任何機(jī)制來保證多個線程的執(zhí)行有序性和原子性。volatile存在的意義是,任何線程對a的修改,都會馬上被其他線程讀取到,因?yàn)橹苯硬僮髦鞔?沒有線程對工作內(nèi)存和主存的同步。所以,volatile的使用場景是有限的,在有限的一些情形下可以使用volatile變量替代鎖。要使 volatile變量提供理想的線程安全,必須同時滿足下面兩個條件[5]。

        (1)對變量的寫操作不依賴于當(dāng)前值。

        (2)該變量沒有包含在具有其他變量的不變式中。

        volatile只保證了可見性,所以Volatile適合直接賦值的場景,如:

        在沒有volatile聲明時,多線程環(huán)境下,a的最終值不一定是正確的,因?yàn)閠his.a=a;涉及到給a賦值和將a同步回主存的步驟,這個順序可能被打亂。如果用volatile聲明了,讀取主存副本到工作內(nèi)存和同步a到主存的步驟,相當(dāng)于是一個原子操作。所以簡單來說,volatile適合這種場景:一個變量被多個線程共享,線程直接給這個變量賦值。這是一種很簡單的同步場景,這時候使用volatile的開銷將會非常小。

        5 結(jié)束語

        使用synchronized關(guān)鍵字、volatile關(guān)鍵字可以為多線程的同步提供基本的安全保障,在開發(fā)高安全性的Java程序時,為了防止競爭冒險、死鎖、活動鎖和資源耗等情況的發(fā)生,我們必須對線程的等待機(jī)制、資源占有機(jī)制等作詳細(xì)的研究與規(guī)劃,不僅要在線程的運(yùn)行機(jī)制上認(rèn)真探索,還要在程序的整體構(gòu)建上作合理的部署,這也是在以后的研究中對這一類問題的從微觀到宏觀的一個研究轉(zhuǎn)變。

        [1]吳其慶.Java編程思想與實(shí)踐[M].北京:冶金工業(yè)出版社,2002.

        [2]包景州.Web服務(wù)中安全身份認(rèn)證系統(tǒng)的設(shè)計和研究[D].上海:上海交通大學(xué),2004.

        [3]李尊朝,蘇軍.Java語言程序設(shè)計[M].北京:中國鐵道出版社,2004.

        [4]沈 袁.實(shí)時Java平臺的研究[D].無錫:江南大學(xué), 2009.

        [5]金振乾.Java語言中read方法分析[J].科技信息,2010 (27):71.

        猜你喜歡
        副本盤子線程
        放桃子
        面向流媒體基于蟻群的副本選擇算法①
        盤子中的童話故事
        淺談linux多線程協(xié)作
        副本放置中的更新策略及算法*
        “撕”掉的盤子
        金盤子溜走了
        樹形網(wǎng)絡(luò)中的副本更新策略及算法*
        Linux線程實(shí)現(xiàn)技術(shù)研究
        么移動中間件線程池并發(fā)機(jī)制優(yōu)化改進(jìn)
        97色偷偷色噜噜狠狠爱网站| 日本一区二区三区小视频| 久久国产劲爆内射日本| 中文字幕亚洲一区二区三区| 成年女人免费v片| 中文 在线 日韩 亚洲 欧美| 国产欧美精品区一区二区三区| 国产欧美日本亚洲精品一4区| 一本之道加勒比在线观看| 亚洲国产精品中文字幕久久| 久久婷婷五月综合色欧美| 国产自偷自偷免费一区| 日韩最新在线不卡av| 国产精品美女自在线观看| 国产麻豆精品传媒av在线| 人妻中文字幕无码系列| 国产精品无套内射迪丽热巴| 亚洲成A人A∨久在线观看| 免费观看一区二区三区视频| 2021国产精品视频网站| 国产免费人成视频在线观看| av无码天一区二区一三区| 日本最新在线一区二区| 激情久久黄色免费网站| 天天爽夜夜爽人人爽| 成人做爰视频www| 成人无码激情视频在线观看| 中文字幕日本在线乱码| 日韩精品人成在线播放| 老熟妇仑乱视频一区二区| 亚洲精品国产品国语在线app | 亚洲日本中文字幕高清在线| 亚洲精品白浆高清久久久久久 | 91精品国产综合久久精品密臀| 麻豆md0077饥渴少妇| 亚洲av永久无码天堂网手机版| 音影先锋色天堂av电影妓女久久| 自拍情爱视频在线观看| 一边捏奶头一边高潮视频| 男受被做哭激烈娇喘gv视频| 国产永久免费高清在线观看视频|