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

java多線(xiàn)程編程之Synchronized塊同步方法

 更新時(shí)間:2015年12月02日 15:05:50   投稿:lijiao  
這篇文章主要介紹了java多線(xiàn)程編程之Synchronized塊同步方法,synchronized關(guān)鍵字又稱(chēng)同步鎖,當(dāng)方法執(zhí)行完后,會(huì)自動(dòng)釋放鎖鎖,只有一個(gè)線(xiàn)程能進(jìn)入此方法,看看下文中各種例子對(duì)synchronized的詳細(xì)解釋

文章分享了4個(gè)例子對(duì)synchronized的詳細(xì)解釋

1、是否加synchronized關(guān)鍵字的不同

public class ThreadTest {

  public static void main(String[] args) {
    Example example = new Example();

    Thread t1 = new Thread1(example);
    Thread t2 = new Thread1(example);
    t1.start();
    t2.start();
  }
}

class Example {
  public synchronized void excute() {
    for (int i = 0; i < 5; ++i) {
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println("excute:" + i);
    }

  }

}

class Thread1 extends Thread {
  private Example example;

  public Thread1(Example example) {
    this.example = example;
  }

  @Override
  public void run() {
    example.excute();
  }
}

加了synchronized關(guān)鍵字的輸出結(jié)果如下

會(huì)先輸出一組0-4,接著再輸出下一組,兩個(gè)線(xiàn)程順序執(zhí)行

excute:0
excute:1
excute:2
excute:3
excute:4
excute:0
excute:1
excute:2
excute:3
excute:4

沒(méi)加synchronized關(guān)鍵字的輸出結(jié)果如下

兩個(gè)線(xiàn)程同時(shí)執(zhí)行excute方法,同時(shí)并發(fā)的

excute:0
excute:0
excute:1
excute:1
excute:2
excute:2
excute:3
excute:3
excute:4
excute:4

2、多個(gè)方法的多線(xiàn)程情況

public class ThreadTest {

  public static void main(String[] args) {
    Example example = new Example();

    Thread t1 = new Thread1(example);
    Thread t2 = new Thread2(example);
    t1.start();
    t2.start();
  }
}

class Example {
  public synchronized void excute() {
    for (int i = 0; i < 5; ++i) {
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println("excute:" + i);
    }
  }
  public synchronized void excute1() {
    for (int i = 0; i < 5; ++i) {
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println("excute1:" + i);
    }
  }

}

class Thread1 extends Thread {
  private Example example;

  public Thread1(Example example) {
    this.example = example;
  }

  @Override
  public void run() {
    example.excute();
  }
}

class Thread2 extends Thread {
  private Example example;

  public Thread2(Example example) {
    this.example = example;
  }

  @Override
  public void run() {
    example.excute1();
  }
}

執(zhí)行結(jié)果如下

同樣是順序執(zhí)行,執(zhí)行完一個(gè)線(xiàn)程再執(zhí)行另一個(gè)線(xiàn)程

excute:0
excute:1
excute:2
excute:3
excute:4
excute1:0
excute1:1
excute1:2
excute1:3
excute1:4

如果去掉synchronized關(guān)鍵字,則兩個(gè)方法并發(fā)執(zhí)行,并沒(méi)有相互影響。

但是如例子程序中所寫(xiě),即便是兩個(gè)方法:

執(zhí)行結(jié)果永遠(yuǎn)是執(zhí)行完一個(gè)線(xiàn)程的輸出再執(zhí)行另一個(gè)線(xiàn)程的?! ?/p>

說(shuō)明:

  如果一個(gè)對(duì)象有多個(gè)synchronized方法,某一時(shí)刻某個(gè)線(xiàn)程已經(jīng)進(jìn)入到了某個(gè)synchronized方法,那么在該方法沒(méi)有執(zhí)行完畢前,其他線(xiàn)程是無(wú)法訪(fǎng)問(wèn)該對(duì)象的任何synchronized方法的。

結(jié)論:

  當(dāng)synchronized關(guān)鍵字修飾一個(gè)方法的時(shí)候,該方法叫做同步方法。

  Java中的每個(gè)對(duì)象都有一個(gè)鎖(lock),或者叫做監(jiān)視器(monitor),當(dāng)一個(gè)線(xiàn)程訪(fǎng)問(wèn)某個(gè)對(duì)象的synchronized方法時(shí),將該對(duì)象上鎖,其他任何線(xiàn)程都無(wú)法再去訪(fǎng)問(wèn)該對(duì)象的synchronized方法了(這里是指所有的同步方法,而不僅僅是同一個(gè)方法),直到之前的那個(gè)線(xiàn)程執(zhí)行方法完畢后(或者是拋出了異常),才將該對(duì)象的鎖釋放掉,其他線(xiàn)程才有可能再去訪(fǎng)問(wèn)該對(duì)象的synchronized方法。

  注意這時(shí)候是給對(duì)象上鎖,如果是不同的對(duì)象,則各個(gè)對(duì)象之間沒(méi)有限制關(guān)系。

  嘗試在代碼中構(gòu)造第二個(gè)線(xiàn)程對(duì)象時(shí)傳入一個(gè)新的Example對(duì)象,則兩個(gè)線(xiàn)程的執(zhí)行之間沒(méi)有什么制約關(guān)系。

3、靜態(tài)的同步方法

當(dāng)一個(gè)synchronized關(guān)鍵字修飾的方法同時(shí)又被static修飾,之前說(shuō)過(guò),非靜態(tài)的同步方法會(huì)將對(duì)象上鎖,但是靜態(tài)方法不屬于對(duì)象,而是屬于類(lèi),它會(huì)將這個(gè)方法所在的類(lèi)的Class對(duì)象上鎖。

public class ThreadTest {

  public static void main(String[] args) {
    Example example = new Example();
    Example example2 = new Example();
    Thread t1 = new Thread1(example);
    Thread t2 = new Thread2(example2);
    t1.start();
    t2.start();
  }
}

class Example {
  public synchronized static void excute() {
    for (int i = 0; i < 5; ++i) {
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println("excute:" + i);
    }
  }
  public synchronized static void excute1() {
    for (int i = 0; i < 5; ++i) {
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println("excute1:" + i);
    }
  }

}

class Thread1 extends Thread {
  private Example example;

  public Thread1(Example example) {
    this.example = example;
  }

  @Override
  public void run() {
    example.excute();
  }
}

class Thread2 extends Thread {
  private Example example;

  public Thread2(Example example) {
    this.example = example;
  }

  @Override
  public void run() {
    example.excute1();
  }
}

執(zhí)行結(jié)果如下

excute:0
excute:1
excute:2
excute:3
excute:4
excute1:0
excute1:1
excute1:2
excute1:3
excute1:4

如果沒(méi)有static修飾符,兩個(gè)線(xiàn)程分別傳入不同的對(duì)象,則會(huì)同時(shí)并發(fā)執(zhí)行

所以如果是靜態(tài)方法的情況(execute()和execute2()都加上static關(guān)鍵字),即便是向兩個(gè)線(xiàn)程傳入不同的Example對(duì)象,這兩個(gè)線(xiàn)程仍然是互相制約的,必須先執(zhí)行完一個(gè),再執(zhí)行下一個(gè)。

結(jié)論:

  如果某個(gè)synchronized方法是static的,那么當(dāng)線(xiàn)程訪(fǎng)問(wèn)該方法時(shí),它鎖的并不是synchronized方法所在的對(duì)象,而是synchronized方法所在的類(lèi)所對(duì)應(yīng)的Class對(duì)象。Java中,無(wú)論一個(gè)類(lèi)有多少個(gè)對(duì)象,這些對(duì)象會(huì)對(duì)應(yīng)唯一一個(gè)Class對(duì)象,因此當(dāng)線(xiàn)程分別訪(fǎng)問(wèn)同一個(gè)類(lèi)的兩個(gè)對(duì)象的兩個(gè)static,synchronized方法時(shí),它們的執(zhí)行順序也是順序的,也就是說(shuō)一個(gè)線(xiàn)程先去執(zhí)行方法,執(zhí)行完畢后另一個(gè)線(xiàn)程才開(kāi)始。

4.synchronized塊

synchronized(object)

{     

}

表示線(xiàn)程在執(zhí)行的時(shí)候會(huì)將object對(duì)象上鎖。(注意這個(gè)對(duì)象可以是任意類(lèi)的對(duì)象,也可以使用this關(guān)鍵字)。

這樣就可以自行規(guī)定上鎖對(duì)象。

public class ThreadTest {

  public static void main(String[] args) {
    Example example = new Example();
    Thread t1 = new Thread1(example);
    Thread t2 = new Thread2(example);
    t1.start();
    t2.start();
  }
}

class Example {
  public void excute() {
    synchronized (this) {
      for (int i = 0; i < 5; ++i) {
        try {
          Thread.sleep(1000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        System.out.println("excute:" + i);
      }
    }
    
  }
  public void excute1() {
    synchronized (this) {
      for (int i = 0; i < 5; ++i) {
        try {
          Thread.sleep(1000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        System.out.println("excute1:" + i);
      }
    }
    
  }

}

class Thread1 extends Thread {
  private Example example;

  public Thread1(Example example) {
    this.example = example;
  }

  @Override
  public void run() {
    example.excute();
  }
}

class Thread2 extends Thread {
  private Example example;

  public Thread2(Example example) {
    this.example = example;
  }

  @Override
  public void run() {
    example.excute1();
  }
}

執(zhí)行結(jié)果如下

excute:0
excute:1
excute:2
excute:3
excute:4
excute1:0
excute1:1
excute1:2
excute1:3
excute1:4

例子程序4所達(dá)到的效果和例子程序2的效果一樣,都是使得兩個(gè)線(xiàn)程的執(zhí)行順序進(jìn)行,而不是并發(fā)進(jìn)行,當(dāng)一個(gè)線(xiàn)程執(zhí)行時(shí),將object對(duì)象鎖住,另一個(gè)線(xiàn)程就不能執(zhí)行對(duì)應(yīng)的塊。

synchronized方法實(shí)際上等同于用一個(gè)synchronized塊包住方法中的所有語(yǔ)句,然后在synchronized塊的括號(hào)中傳入this關(guān)鍵字。當(dāng)然,如果是靜態(tài)方法,需要鎖定的則是class對(duì)象?! ?/p>

可能一個(gè)方法中只有幾行代碼會(huì)涉及到線(xiàn)程同步問(wèn)題,所以synchronized塊比synchronized方法更加細(xì)粒度地控制了多個(gè)線(xiàn)程的訪(fǎng)問(wèn),只有synchronized塊中的內(nèi)容不能同時(shí)被多個(gè)線(xiàn)程所訪(fǎng)問(wèn),方法中的其他語(yǔ)句仍然可以同時(shí)被多個(gè)線(xiàn)程所訪(fǎng)問(wèn)(包括synchronized塊之前的和之后的)。

結(jié)論:

  synchronized方法是一種粗粒度的并發(fā)控制,某一時(shí)刻,只能有一個(gè)線(xiàn)程執(zhí)行該synchronized方法;

  synchronized塊則是一種細(xì)粒度的并發(fā)控制,只會(huì)將塊中的代碼同步,位于方法內(nèi)、synchronized塊之外的其他代碼是可以被多個(gè)線(xiàn)程同時(shí)訪(fǎng)問(wèn)到的。

以上就是關(guān)于java多線(xiàn)程編程Synchronized塊同步方法,希望對(duì)大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • 詳解Java如何優(yōu)雅的處理異常

    詳解Java如何優(yōu)雅的處理異常

    在編寫(xiě) Java 程序的過(guò)程中,有一種異常幾乎每個(gè)開(kāi)發(fā)者都會(huì)遇到——空指針異常(NullPointerException),那么我們應(yīng)該如何有效且優(yōu)雅的處理空指針異常呢,下面小編就來(lái)詳細(xì)介紹這個(gè)處理方案吧
    2023-08-08
  • MybatisPlus實(shí)現(xiàn)對(duì)象嵌套關(guān)聯(lián)查詢(xún)一對(duì)多List集合查詢(xún)

    MybatisPlus實(shí)現(xiàn)對(duì)象嵌套關(guān)聯(lián)查詢(xún)一對(duì)多List集合查詢(xún)

    這篇文章主要介紹了MybatisPlus實(shí)現(xiàn)對(duì)象嵌套關(guān)聯(lián)查詢(xún)一對(duì)多List集合查詢(xún),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Windows系統(tǒng)中Java調(diào)用cmd命令及執(zhí)行exe程序的方法

    Windows系統(tǒng)中Java調(diào)用cmd命令及執(zhí)行exe程序的方法

    這篇文章主要介紹了Windows系統(tǒng)中Java調(diào)用cmd命令及執(zhí)行exe程序的方法,主要用到了IOException類(lèi),需要的朋友可以參考下
    2016-03-03
  • SpringBoot配置默認(rèn)HikariCP數(shù)據(jù)源

    SpringBoot配置默認(rèn)HikariCP數(shù)據(jù)源

    咱們開(kāi)發(fā)項(xiàng)目的過(guò)程中用到很多的開(kāi)源數(shù)據(jù)庫(kù)鏈接池,比如druid、c3p0、BoneCP等等,本文主要介紹了SpringBoot配置默認(rèn)HikariCP數(shù)據(jù)源,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-11-11
  • 一文告訴你為什么要重寫(xiě)hashCode()方法和equals()方法

    一文告訴你為什么要重寫(xiě)hashCode()方法和equals()方法

    本篇文章帶大家了解一下為什么重寫(xiě)hashCode()方法和equals()方法,文中有非常詳細(xì)的說(shuō)明以及代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們很有幫助,需要的朋友可以參考下
    2021-05-05
  • 一文搞懂Spring中的Bean作用域

    一文搞懂Spring中的Bean作用域

    scope用來(lái)聲明容器中的對(duì)象所應(yīng)該處的限定場(chǎng)景或者說(shuō)該對(duì)象的存活時(shí)間,即容器在對(duì)象進(jìn)入其 相應(yīng)的scope之前,生成并裝配這些對(duì)象,在該對(duì)象不再處于這些scope的限定之后,容器通常會(huì)銷(xiāo)毀這些對(duì)象,這篇文章主要介紹了Spring中的Bean作用域,需要的朋友可以參考下
    2022-06-06
  • 簡(jiǎn)單了解SpringBoot HATEOAS使用方法

    簡(jiǎn)單了解SpringBoot HATEOAS使用方法

    這篇文章主要介紹了簡(jiǎn)單了解SpringBoot HATEOAS使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • Java的遞歸算法詳解

    Java的遞歸算法詳解

    Java遞歸算法是基于Java語(yǔ)言實(shí)現(xiàn)的遞歸算法。遞歸算法對(duì)解決一大類(lèi)問(wèn)題很有效,它可以使算法簡(jiǎn)潔和易于理解。接下來(lái)通過(guò)本文給大家介紹Java遞歸算法相關(guān)知識(shí),感興趣的朋友一起學(xué)習(xí)吧
    2021-09-09
  • Java中Cglib代理類(lèi)重寫(xiě)邏輯詳解

    Java中Cglib代理類(lèi)重寫(xiě)邏輯詳解

    這篇文章主要介紹了Java中Cglib代理類(lèi)重寫(xiě)邏輯詳解,代理類(lèi)中只會(huì)維護(hù)NoOp這個(gè)回調(diào)屬性,并不會(huì)生成目標(biāo)類(lèi)MyService中的noOp所對(duì)應(yīng)的方法,需要的朋友可以參考下
    2023-11-11
  • Servlet實(shí)現(xiàn)文件下載功能

    Servlet實(shí)現(xiàn)文件下載功能

    這篇文章主要為大家詳細(xì)介紹了Servlet實(shí)現(xiàn)文件下載功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12

最新評(píng)論

乌兰察布市| 高淳县| 乡宁县| 策勒县| 三都| 永仁县| 沙雅县| 读书| 金门县| 永嘉县| 毕节市| 焉耆| 鄄城县| 兴文县| 江陵县| 喜德县| 多伦县| 行唐县| 普定县| 西乌| 柳林县| 阿克苏市| 定远县| 依安县| 慈利县| 房产| 葫芦岛市| 阳城县| 六安市| 汉寿县| 岳西县| 甘泉县| 临沂市| 奉新县| 汉中市| 共和县| 疏勒县| 西充县| 广东省| 平南县| 铜陵市|