最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java多線程編程中synchronized關(guān)鍵字的基礎(chǔ)用法講解

 更新時間:2016年06月15日 11:59:23   作者:ciding  
Java的synchronized關(guān)鍵字用于修飾線程同步,用以線程資源共享的目的等,下面就帶來簡單的Java多線程編程中synchronized關(guān)鍵字的基礎(chǔ)用法講解

多線程編程中,最關(guān)鍵、最關(guān)心的問題應(yīng)該就是同步問題,這是一個難點,也是核心。
從jdk最早的版本的synchronized、volatile,到j(luò)dk 1.5中提供的java.util.concurrent.locks包中的Lock接口(實現(xiàn)有ReadLock,WriteLock,ReentrantLock),多線程的實現(xiàn)也是一步步走向成熟化。
 
同步,它是通過什么機制來控制的呢?第一反應(yīng)就是鎖,這個在學習操作系統(tǒng)與數(shù)據(jù)庫的時候,應(yīng)該都已經(jīng)接觸到了。在Java的多線程程序中,當多個程序競爭同一個資源時,為了防止資源的腐蝕,給第一個訪問資源的線程分配一個對象鎖,而后來者需要等待這個對象鎖的釋放。
 
是的,Java線程的同步,最關(guān)心的是共享資源的使用。
 
先來了解一些有哪些線程的共享資源,
從JVM中了解有哪些線程共享的數(shù)據(jù)是需要進行協(xié)調(diào):
1,保存在堆中的實例變量;2,保存在方法區(qū)的類變量。
 
而在Java虛擬機加載類的時候,每個對象或類都會與一個監(jiān)視器相關(guān)聯(lián),用來保護對象的實例變量或類變量;當然,如果對象沒有實例變量,或類沒有變量,監(jiān)視器就什么也不監(jiān)視了。
 
為了實現(xiàn)上面的說的監(jiān)視器的互斥性,虛擬機為每一個對象或類都關(guān)聯(lián)了一個鎖(也叫隱形鎖),這里說明一下,類鎖也是通過對象鎖來實現(xiàn)的,因為在類加載的時候,JVM會為每一個類創(chuàng)建一個java.lang.Class的一個實例;所以當鎖對對象的時候,也就鎖住這個類的類對象。
 
另外,一個線程是可以對一個對象進行多次上鎖,也就對應(yīng)著多次釋放;它是通過JVM為每個對象鎖提供的lock計算器,上一次鎖,就加1,對應(yīng)的減1,當計算器的值為0時,就釋放。這個對象鎖是JVM內(nèi)部的監(jiān)視器使用的,也是由JVM自動生成的,所有程序猿就不用自己動手來加了。
 
介紹完java的同步原理后,我們進入正題,先來說說synchronized的使用,而其它的同步,將在后面的章節(jié)中介紹。
 
先來運行一個例子試試。

package thread_test; 
 
/** 
 * 測試擴展Thread類實現(xiàn)的多線程程序 
 * 
 */ 
public class TestThread extends Thread{  
  private int threadnum; 
 
  public TestThread(int threadnum) {  
    this.threadnum = threadnum;  
  } 
   
  @Override 
  public synchronized void run() {  
    for(int i = 0;i<1000;i++){  
          System.out.println("NO." + threadnum + ":" + i ); 
    } 
    }  
   
    public static void main(String[] args) throws Exception {  
      for(int i=0; i<10; i++){ 
          new TestThread(i).start(); 
          Thread.sleep(1); 
      } 
    }  
} 

 
運行結(jié)果:

NO.0:887 
NO.0:888 
NO.0:889 
NO.0:890 
NO.0:891 
NO.0:892 
NO.0:893 
NO.0:894 
NO.7:122 
NO.7:123 
NO.7:124 

上面只是一個片段,說明一個問題而已。
細心的童鞋會發(fā)現(xiàn),NO.0:894后面是NO.7:122,也就是說沒有按照從0開始到999。
都說synchronized可以實現(xiàn)同步方法或同步塊,這里怎么就不行呢?
 
先從同步的機制來分析一下,同步是通過鎖來實現(xiàn)的,那么上面的例子中,鎖定了什么對象,或鎖定了什么類呢?里面有兩個變量,一個是i,一個是threadnum;i是方法內(nèi)部的,threadnum是私有的。
再來了解一下synchronized的運行機制:
      在java程序中,當使用synchronized塊或synchronized方法時,標志這個區(qū)域進行監(jiān)視;而JVM在處理程序時,當有程序進入監(jiān)視區(qū)域時,就會自動鎖上對象或類。
 
那么上面的例子中,synchronized關(guān)鍵字用上后,鎖定的是什么呢?
當synchronized方法時,鎖定調(diào)用方法的實例對象本身做為對象鎖。本例中,10個線程都有自己創(chuàng)建的TestThread的類對象,所以獲取的對象鎖,也是自己的對象鎖,與其它線程沒有任何關(guān)系。
 
要實現(xiàn)方法鎖定,必須鎖定有共享的對象。
 
對上面的實例修改一下,再看看:

package thread_test; 
 
/** 
 * 測試擴展Thread類實現(xiàn)的多線程程序 
 * 
 */ 
public class TestThread extends Thread{  
  private int threadnum; 
  private String flag;  //標記 
   
  public TestThread(int threadnum,String flag) {  
       this.threadnum = threadnum;  
        this.flag = flag; 
    } 
   
  @Override 
    public void run() {  
    synchronized(flag){ 
      for(int i = 0;i<1000;i++){  
              System.out.println("NO." + threadnum + ":" + i ); 
          }  
    } 
    }  
 
    public static void main(String[] args) throws Exception {  
      String flag = new String("flag"); 
      for(int i=0; i<10; i++){ 
          new TestThread(i,flag).start(); 
          Thread.sleep(1); 
      } 
    }  
} 

 
也就加了一個共享的標志flag。然后在通過synchronized塊,對flag標志進行同步;這就滿足了鎖定共享對象的條件。
是的,運行結(jié)果,已經(jīng)按順序來了。

通過synchronized塊,指定獲取對象鎖來達到同步的目的。那有沒有其它的方法,可以通過synchronized方法來實現(xiàn)呢?
 
根據(jù)同步的原理:如果能獲取一個共享對象鎖或類鎖,及可實現(xiàn)同步。那么我們是不是可以通過共享一個類鎖來實現(xiàn)呢?
 
是的,我們可以使用靜態(tài)同步方法,根據(jù)靜態(tài)方法的特性,它只允許類對象本身才可以調(diào)用,不能通過實例化一個類對象來調(diào)用。那么如果獲得了這個靜態(tài)方法的鎖,也就是獲得這個類鎖,而這個類鎖都是TestThread類鎖,及達到了獲取共享類鎖的目的。
 
實現(xiàn)代碼如下:

package thread_test; 
 
/** 
 * 測試擴展Thread類實現(xiàn)的多線程程序 
 * 
 * @author ciding 
 * @createTime Dec 7, 2011 9:37:25 AM 
 * 
 */ 
public class TestThread extends Thread{  
  private int threadnum; 
   
  public TestThread(int threadnum) {  
    this.threadnum = threadnum;  
  } 
   
  public static synchronized void staticTest(int threadnum) {  
    for(int i = 0;i<1000;i++){  
      System.out.println("NO." + threadnum + ":" + i ); 
    }  
  }  
 
  public static void main(String[] args) throws Exception {  
    for(int i=0; i<10; i++){ 
      new TestThread(i).start(); 
      Thread.sleep(1); 
    } 
  }  
   
  @Override 
  public void run(){ 
    staticTest(threadnum); 
  } 
} 

 運行結(jié)果略,與第二個例子中一樣。
 
 
以上的內(nèi)容主要是說明兩個問題:同步塊與同步方法。
1,同步塊:獲取的對象鎖是synchronized(flag)中的flag對象鎖。
2,同步方法:獲取的是方法所屬的類對象,及類對象鎖。
靜態(tài)同步方法,由于多個線程都會共享,所以一定會同步。
而非靜態(tài)同步方法,只有在單例模式下才會同步。

相關(guān)文章

  • java?executor包參數(shù)處理功能?

    java?executor包參數(shù)處理功能?

    這篇文章主要介紹了java?executor包參數(shù)處理功能,sql語句中的參數(shù)賦值是有由executor包中的parameter子包完成的。parameter子包其實只有一個parameterHandler接口并且它定義了兩個方法,下面我們就來看詳細內(nèi)容吧,需要的朋友可以參考一下
    2022-02-02
  • IDEA中Git的基本應(yīng)用詳解

    IDEA中Git的基本應(yīng)用詳解

    這篇文章主要介紹了IDEA中Git的基本應(yīng)用詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • Java substring方法實現(xiàn)原理解析

    Java substring方法實現(xiàn)原理解析

    這篇文章主要介紹了Java substring方法實現(xiàn)原理解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • mybatis 映射文件中if標簽判斷字符串相等的兩種方式

    mybatis 映射文件中if標簽判斷字符串相等的兩種方式

    這篇文章主要介紹了mybatis 映射文件中if標簽判斷字符串相等的方式,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-06-06
  • IDEA?Eval?Reset?使用方法匯總

    IDEA?Eval?Reset?使用方法匯總

    本文給大家介紹了IDEA?Eval?Reset?使用方法,安裝插件包括離線安裝方式和在線安裝方式,本文給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • es(elasticsearch)整合SpringCloud(SpringBoot)搭建教程詳解

    es(elasticsearch)整合SpringCloud(SpringBoot)搭建教程詳解

    這篇文章主要介紹了es(elasticsearch)整合SpringCloud(SpringBoot)搭建教程,本文通過實例圖文相結(jié)合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • Spring中的事務(wù)管理及實現(xiàn)方式解析

    Spring中的事務(wù)管理及實現(xiàn)方式解析

    這篇文章主要介紹了Spring中的事務(wù)管理及實現(xiàn)方式解析,Spring事務(wù)管理基于底層數(shù)據(jù)庫本身的事務(wù)處理機制,數(shù)據(jù)庫事務(wù)的基礎(chǔ),是掌握Spring事務(wù)管理的基礎(chǔ),這篇總結(jié)下Spring事務(wù),需要的朋友可以參考下
    2024-01-01
  • java解析XML Node與Element的區(qū)別(推薦)

    java解析XML Node與Element的區(qū)別(推薦)

    下面小編就為大家分享一篇java解析XML Node與Element的區(qū)別,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • 如何使用Spring Security手動驗證用戶的方法示例

    如何使用Spring Security手動驗證用戶的方法示例

    這篇文章主要介紹了如何使用Spring Security手動驗證用戶的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • vscode搭建java開發(fā)環(huán)境的實現(xiàn)步驟

    vscode搭建java開發(fā)環(huán)境的實現(xiàn)步驟

    本文主要介紹了vscode搭建java開發(fā)環(huán)境,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03

最新評論

金湖县| 清水县| 交口县| 会东县| 北票市| 罗山县| 德庆县| 大埔区| 时尚| 泌阳县| 隆安县| 木兰县| 铜陵市| 乐清市| 闸北区| 克拉玛依市| 保定市| 连山| 波密县| 水城县| 汤阴县| 西和县| 舟曲县| 重庆市| 南平市| 徐水县| 平江县| 济阳县| 斗六市| 唐海县| 灌阳县| 株洲市| 衡水市| 怀集县| 长治市| 壤塘县| 杭锦后旗| 蒲城县| 奉化市| 揭阳市| 宽城|