• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      Java多線程同步機制研究分析

      2014-05-30 21:55:08李娟
      關(guān)鍵詞:多線程同步

      李娟

      摘 要:Java多線程同步機制的應(yīng)用有利于提高系統(tǒng)資源的利用率,改善系統(tǒng)的安全性。但是在多線程中最重要的問題是線程的同步和共享資源的訪問保護。本文通過具有意義的售票系統(tǒng)的并發(fā)同步實例,對同步進行了探索。

      關(guān)鍵詞:Java 多線程 同步

      中圖分類號:G420 文獻標(biāo)識碼:A 文章編號:1673-9795(2014)03(a)-0183-02

      至今,隨著計算機技術(shù)的飛速發(fā)展和互聯(lián)網(wǎng)的大面積普及,多處理器計算機已經(jīng)司空見慣,在這種前景下,Java虛擬機(JVM)提供了一個多線程機制。在Java語言的編程設(shè)計中使用多線程運行機制來支持多任務(wù)和并行處理,可以讓在同一地址空間中執(zhí)行多控制流,顯著的提高程序效率。但是線程的同步問題和共享資源的訪問保護是非常復(fù)雜的問題。

      1 線程的同步機制

      多線程的應(yīng)用程序中,兩個或兩個以上的線程可以共享同一片存儲空間,這帶來方便的同時,也導(dǎo)致線程共享資源發(fā)生沖突,此時我們可以使用Java語言提供的同步機制(又叫互斥鎖機制)來解決此沖突問題。該同步機制是使用synchronized關(guān)鍵字控制一段程序代碼,這代碼段稱為互斥區(qū)或臨界區(qū)。定義臨界區(qū)的目的是在任一時間只有一個線程使用共享資源,保證多線程的并發(fā)執(zhí)行。Java語言的每個對象(即類實例)都對應(yīng)一把鎖(Lock),臨界區(qū)使用鎖來互斥多線程進入臨界區(qū)。每次只有一個線程獲得鎖進入臨界區(qū),其它沒有獲得鎖的線程必須在就緒隊列中等待,直到該鎖被釋放。synchronized關(guān)鍵字的使用方式有synchronized方法和塊兩種。

      (1)synchronized方法:將訪問共享資源的方法都標(biāo)記為synchronized,然后該標(biāo)記的方法來控制對類成員變量的訪問。類實例和鎖是一一對應(yīng)的,當(dāng)獲得需要調(diào)用synchronized方法的類實例鎖時,synchronized方法才可以執(zhí)行,而且它開始執(zhí)行直到完畢為止獨占鎖。這時其它調(diào)用synchronized方法的線程進入阻塞,一直到獲得釋放鎖為止。定義同步方法語法格式如下:

      public synchronized void 方法名(參數(shù)列表){

      …//省略代碼

      }

      (2)synchronized塊:java語言中除了使用synchronized方法來設(shè)置同步,還可以使用synchronized塊來設(shè)置同步。如果使用前者來修飾一個比較大的方法時,也會鎖住了不需要鎖住的字段,導(dǎo)致程序運行效率降低。后者是把程序的某段代碼使用synchronized塊來修飾,跟前者比它可以減少程序的同步區(qū)域。所以我們可以使用synchronized塊來修飾語句塊,能夠彌補synchronized方法修飾的缺陷。定義同步塊的語法格式如下:

      synchronized(表達式)//表達式的結(jié)果是當(dāng)前對象{

      …//省略代碼

      }

      從以上兩種方法能夠看出,關(guān)鍵字synchronized用來與對象的鎖聯(lián)系,當(dāng)某個對象使用synchronized修飾時就意味著同步機制已啟動,任一時刻只有讓一個線程訪問臨界區(qū)資源,阻止其他線程訪問該對象,即使出現(xiàn)阻塞和死鎖現(xiàn)象,該對象的被鎖定狀態(tài)也不會解除。

      2 同步機制在售票系統(tǒng)的實現(xiàn)

      在現(xiàn)實生活當(dāng)中也經(jīng)常遇到多個線程共享同一個數(shù)據(jù)資源,典型的例子是火車票售票系統(tǒng),來講解線程共享資源。假設(shè)在售票廳內(nèi)設(shè)10個售票窗口,每個售票窗口相當(dāng)于一個線程,這些線程的共同訪問資源為售票廳的100張票。若不設(shè)置同步機制代碼如下:

      public class Ticket {

      public static void main(String[] args) {

      Sell_Ticket st = new Sell_Ticket();//創(chuàng)建10個線程,每個線程代表一個售票口

      for (int i = 0; i < 10; i++) new Thread(st, "第" + i + "個窗口").start();

      }

      }

      class Sell_Ticket implements Runnable {

      int trainTicket = 100;//預(yù)售的票數(shù)

      boolean flag = false;//循環(huán)控制標(biāo)志

      public void run(){

      while (!flag) {// 當(dāng)還有剩余票時繼續(xù)售票

      sellTicket(); }

      }

      public void sellTicket(){

      if (trainTicket > 0) {

      System.out.println(Thread.currentThread().getName()+ "售票成功,剩余票數(shù):"

      + trainTicket);

      trainTicket--;

      } else flag = true;

      }

      }

      運行的結(jié)果是多個窗口同時售票,會出現(xiàn)剩余票數(shù)變?yōu)樨摂?shù)的情況,即10個線程從100張票賣到1張票的時候還沒有停止賣,系統(tǒng)出現(xiàn)繼續(xù)賣出負數(shù)票的現(xiàn)象。

      下面通過Java的多線程同步機制的synchronized方法和塊兩種方式來分別解決以上出現(xiàn)的問題。為了便于觀察到運行錯誤,特意添加Thread.sleep(10)方法,讓每個線程在售票階段睡眠10 ms。

      (1)使用synchronized方法:在售票方法sellTicket()的前面添加synchronized關(guān)鍵字,就相當(dāng)于使用一把鎖鎖住該方法。修改后的程序代碼如下:

      public synchronized void sellTicket(){

      if (trainTicket > 0) {

      try {

      Thread.sleep(10);//睡眠10毫秒

      } catch (InterruptedException e) {e.printStackTrace();}

      System.out.println(Thread.currentThread().getName()+ "售票成功,剩余票數(shù):"+ trainTicket);

      trainTicket--;

      } else flag = true;

      }

      以上是使用synchronized關(guān)鍵字修飾sellTicket()方法,對該方法實現(xiàn)了多線程的互斥訪問。程序運行run()方法以后,當(dāng)判斷出還有剩余票時調(diào)用被加鎖的sellTicket()方法,這時的sellTicket()方法,在同一個時間段內(nèi)只能被一個線程訪問。

      若synchronized關(guān)鍵字修飾靜態(tài)方法sellTicket(),鎖住的就是類本身。因為靜態(tài)方法是所有類實例對象所共享的,因此線程對象在訪問此靜態(tài)方法時是互斥訪問的,從而可以實現(xiàn)線程的同步。實現(xiàn)方法如下所示:

      public static synchronized void sellTicket() {}

      (2)使用synchronized塊:在程序中的if語句外面加synchronized關(guān)鍵字,就相當(dāng)于使用一把鎖鎖住了這段代碼。它不同于同步方法,傳遞一個對象進行同步。修改后的程序如下:

      Object object =new Object();

      public void run() {

      while (!flag) { // 當(dāng)還有剩余票時繼續(xù)售票

      synchronized(object){

      if (trainTicket > 0) {

      try {

      Thread.sleep(10);

      } catch (InterruptedException e) {e.printStackTrace();}

      System.out.println(Thread.currentThread().getName()+ "售票成功,剩余票數(shù):"

      + trainTicket);

      trainTicket--;

      } else flag = true;

      }

      }

      }

      以上是使用synchronized關(guān)鍵字修飾了售票代碼段,對該代碼段實現(xiàn)了多線程的互斥訪問。同步塊不像同步方法修飾整個方法,而修飾一段代碼即可。synchronized(object)傳遞的是一個對象object,如果多線程想使用該對象的方法和變量,首先判斷有沒有加鎖,若已加鎖,等待鎖的釋放;若沒有鎖,先將給它加鎖,然后去執(zhí)行代碼。在同一個時間段內(nèi)只能有一個線程能夠獲得這把鎖。

      同步塊的關(guān)鍵是多個線程對象競爭同一個共享資源即可,上面的代碼中是通過外部創(chuàng)建共享資源,然后傳遞到線程中來實現(xiàn)。我們也可以利用類成員變量被所有類的實例所共享這一特性,因此可以將object對象用靜態(tài)成員對象來實現(xiàn),如下所示:

      static Object object =new Object();

      使用synchronized方法和塊兩種方式修改后的運行結(jié)果相同,剩余票數(shù)每次減1,從100減到0,到0時flag=true,while循環(huán)結(jié)束,即不能售票。

      3 結(jié)語

      Java程序中通過synchronized關(guān)鍵字來實現(xiàn)互斥訪問。本文引用的售票系統(tǒng),通過synchronized方法和塊兩種方式實現(xiàn)了線程的同步互斥,避免了車票售完以后還能繼續(xù)售票導(dǎo)致數(shù)據(jù)混亂的問題??傊?,合理使用多線程同步機制才能讓數(shù)據(jù)資源得到安全保障。

      參考文獻

      [1] 明日科技.Java從入門到精通[M].3版.北京:清華大學(xué)出版社,2013.

      [2] 沈祥玖,李作緯.操作系統(tǒng)原理與應(yīng)用[M].3版.北京:高等教育出版社,2013.

      [3] 路勇.Java多線程同步問題分析[J].軟件,2012(4):31-33.

      猜你喜歡
      多線程同步
      素質(zhì)教育理念下藝術(shù)教育改革的思路
      Java并發(fā)工具包對并發(fā)編程的優(yōu)化
      政府職能的轉(zhuǎn)變與中國經(jīng)濟結(jié)構(gòu)調(diào)整的同步
      商情(2016年42期)2016-12-23 14:26:58
      公共藝術(shù)與城市設(shè)計的協(xié)調(diào)與同步
      基于多線程文件傳輸關(guān)鍵技術(shù)研究與實現(xiàn)
      網(wǎng)頁爬蟲技術(shù)的關(guān)鍵技術(shù)研究探索
      一種基于多線程的高速磁盤鏡像算法
      一種新型雙軌同步焊接的焊接裝置
      镇原县| 海晏县| 南昌市| 凤翔县| 连山| 新乡市| 天柱县| 曲阳县| 开江县| 天柱县| 自治县| 垦利县| 南汇区| 象州县| 南城县| 汉川市| 苍溪县| 明星| 英超| 丰县| 文成县| 平安县| 湘潭县| 武汉市| 湖北省| 平谷区| 怀柔区| 乐陵市| 普陀区| 宣汉县| 武宣县| 清丰县| 杭州市| 宝山区| 天水市| 砚山县| 靖西县| 莱阳市| 平邑县| 丰镇市| 宜州市|