国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java多線程編程中synchronized關鍵字的基礎用法講解

Java多線程編程中synchronized關鍵字的基礎用法講解

2020-05-17 13:51ciding JAVA教程

Java的synchronized關鍵字用于修飾線程同步,用以線程資源共享的目的等,下面就帶來簡單的Java多線程編程中synchronized關鍵字的基礎用法講解

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package thread_test;
 
/**
 * 測試擴展Thread類實現的多線程程序
 *
 */
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);
      }
    
}

 
運行結果:

?
1
2
3
4
5
6
7
8
9
10
11
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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package thread_test;
 
/**
 * 測試擴展Thread類實現的多線程程序
 *
 */
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標志進行同步;這就滿足了鎖定共享對象的條件。
是的,運行結果,已經按順序來了。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package thread_test;
 
/**
 * 測試擴展Thread類實現的多線程程序
 *
 * @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);
  }
}

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: av网站观看 | 欧美日韩精品一区二区公司 | 精品美女在线观看视频在线观看 | 久久综合久| 精品国产一区二区三区性色av | 国产美女网站视频 | 午夜视频在线播放 | 国产高清视频一区 | 天天干天天操 | 国产高清一区二区三区 | 99这里只有精品 | a欧美| 国产视频久久久久久久 | 在线观看国产精品一区 | 中文字幕一区二区三区乱码图片 | 视频一区二区三区在线播放 | 亚洲大片av | 亚洲国产网站 | 亚洲黄色成人 | 国产精品网站在线观看 | 国产精品毛片一区二区三区 | 粉嫩视频在线观看 | 日韩福利电影 | 成人日日夜夜 | 日韩av资源网 | 日韩午夜av | 久久久久久久久成人 | 日韩高清一区 | 亚洲专区 变态 另类 | 国产精品美女久久久久久久网站 | 亚洲福利在线观看 | 亚洲欧美aa | 青青草亚洲 | 亚洲欧美国产另类 | 亚洲精选久久 | 高清av在线 | 一区二区三区日韩 | 最新日韩视频 | 日韩欧美二区 | 欧美精品一区二区视频 | 免费av一区二区三区 |