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

java多線程的同步方法實(shí)例代碼

 更新時(shí)間:2017年04月26日 14:18:17   投稿:lqh  
這篇文章主要介紹了 java多線程的同步方法實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下

 java多線程的同步方法實(shí)例代碼

先看一個段有關(guān)銀行存錢的代碼:

class Bank {
  private int sum;
  public void add(int num){
    sum = sum + num;
    try {
      Thread.sleep(10);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    System.out.println("total num is : " + sum);
  }
}
class Custom implements Runnable{
  private Bank b = new Bank();

  @Override
  public void run() {
    for(int i = 3 ; i > 0 ; i--)
      b.add(100);
  }
}
public class BankDemo{
  public static void main(String[] args) {
    Custom custom = new Custom();
    Thread t1 = new Thread(custom);
    Thread t2 = new Thread(custom);
    t1.start();
    t2.start();
  }
}

此代碼的運(yùn)行結(jié)果為:

total num is : 100
total num is : 300
total num is : 400
total num is : 500
total num is : 500
total num is : 600

可以看出sum的值與預(yù)期的效果不太一樣;造成這種現(xiàn)象的原因有兩個:

1.程序存在兩個以上的子線程;

2.子線程中存在多條語句操作同一變量;

上述例子中:創(chuàng)建了兩個子線程·t1 和 t2,分別向銀行中存錢。但是可以看出銀行的實(shí)力隨著Custom的創(chuàng)建,只創(chuàng)建了一個對象。也就是說我們只操作一個數(shù)據(jù)變量即為銀行中錢的總數(shù)sum;當(dāng)兩個子線程開啟的時(shí)候run方法中調(diào)用了bank的add方法,而add方法中有兩個語句都在操作sum一個sum的增加,一個是打印sum,當(dāng)兩個子線程搶占cpu執(zhí)行各自的程序的時(shí)候會出現(xiàn):

當(dāng)t1執(zhí)行到add以后,t2搶到了cpu的執(zhí)行權(quán),執(zhí)行也是執(zhí)行了add語句,隨后打印出sum的值,這時(shí)候由于sum增加了兩次,所以打印出來的sum值為200。類推,假如這個時(shí)候t1又搶回了cpu的執(zhí)行權(quán),因此又打印出一次200。

顯然這種現(xiàn)象是我們不希望產(chǎn)生的。我們希望一個線程存完錢然后打印出結(jié)果,之后才允許下一次添加操作。這就是多線程會產(chǎn)生的問題,線程不安全。

我們應(yīng)盡量避免這種現(xiàn)象的發(fā)生,Java給我們提供了三種方法來解決這個問題:

第一種:同步代碼塊

//private Object obj = new Object();
  public void add(int num) {
    synchronized (this) {
      sum = sum + num;
      try {
        Thread.sleep(10);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println("total num is : " + sum);
    }
  }

將多線程中需要操作同一數(shù)據(jù)對象的語句使用同步代碼塊包含。同步代碼塊的原理就是:

1.java中每個對象都有一個內(nèi)置鎖;

2.當(dāng)程序運(yùn)行到同步代碼塊的時(shí)候首先會獲取指定對象的鎖,這個鎖對于多個線程來說是唯一的。我們可以創(chuàng)建任意一個對象(obj)讓他當(dāng)作同步代碼塊的鎖。

3.當(dāng)程序中只有一個只有一個鎖的話我們還可以使用this,this代表當(dāng)前執(zhí)行代碼所操作的實(shí)例對象的鎖。即擁有add方法的類的對象,即bank。

4.兩個并發(fā)線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時(shí),一個時(shí)間內(nèi)只能有一個線程得到執(zhí)行。另一個線程必須等待當(dāng)前線程執(zhí)行完這個代碼塊以后才能執(zhí)行該代碼塊。

這樣就可以操作同一個數(shù)據(jù)的多條語句只能在“同一段時(shí)間”只能被一個子線程所操作。

第二種 同步函數(shù)

 public synchronized void add(int num) {
      sum = sum + num;
      try {
        Thread.sleep(10);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println("total num is : " + sum);
    }

除了同步代碼塊以外我們還可以將需要同步的操作抽象成一個函數(shù),然后將這個函數(shù)用synchronized修飾,形成同步方法。比如上述例子中的add方法中的語句都在操作sum對象。我們就可以將add方法使用synchronized修飾。這樣也能達(dá)到代碼同步的效果。

同步方法使用的鎖其實(shí)就是 this。

值得一提的是:同步方法和同步代碼塊,在開發(fā)程序的時(shí)候我們更推薦使用同步代碼塊。

1.同步代碼塊可以綁定任意對象,而同步函數(shù)只能綁定該類對象this

2.如果多個線程使用同一個鎖的話,那么兩者均可以使用,如果存在多個鎖的(比如,在一個對象的同步方法里面調(diào)用另外一個對象的同步方法,則獲取了兩個對象的同步鎖),只能使用同步代碼塊。
靜態(tài)方法的同步
同步方法

public synchronized static void add(int num){}

同步代碼塊:

public synchronized void add(int num){
  synchronized (Bank.Class) {
  }
}

靜態(tài)方法的默認(rèn)同步鎖是當(dāng)前方法所在類的.class 對象,注意this與static不可以連用,所以不能使用this.Class

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關(guān)文章

  • 淺談java中的對象、類、與方法的重載

    淺談java中的對象、類、與方法的重載

    本文主要對java中的對象、類、與方法的重載進(jìn)行簡要概述,具有一定的參考價(jià)值,需要的朋友一起來看下吧
    2016-12-12
  • Java中compareTo()和compare()方法使用及區(qū)別詳解

    Java中compareTo()和compare()方法使用及區(qū)別詳解

    這篇文章主要介紹了Java中compareTo()和compare()方法使用及區(qū)別的相關(guān)資料,compareTo()方法用于定義類的自然排序,適用于具有單一、固定排序方式的場景,compare()方法提供自定義排序的靈活性,適用于需要根據(jù)不同規(guī)則對對象進(jìn)行排序的場景,需要的朋友可以參考下
    2025-01-01
  • 優(yōu)化Java虛擬機(jī)總結(jié)(jvm調(diào)優(yōu))

    優(yōu)化Java虛擬機(jī)總結(jié)(jvm調(diào)優(yōu))

    這篇文章主要介紹了優(yōu)化Java虛擬機(jī)總結(jié)(jvm調(diào)優(yōu)),具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • Java Servlet中Response對象的使用方法

    Java Servlet中Response對象的使用方法

    本文介紹了Java Servlet中Response對象的使用方法,包括設(shè)置響應(yīng)頭、設(shè)置響應(yīng)編碼、向客戶端發(fā)送數(shù)據(jù)、重定向等操作,同時(shí)介紹了常用的響應(yīng)狀態(tài)碼和響應(yīng)類型,幫助讀者更好地理解和掌握Servlet中Response對象的用法
    2023-05-05
  • Java將網(wǎng)絡(luò)圖片轉(zhuǎn)成輸入流以及將url轉(zhuǎn)成InputStream問題

    Java將網(wǎng)絡(luò)圖片轉(zhuǎn)成輸入流以及將url轉(zhuǎn)成InputStream問題

    這篇文章主要介紹了Java將網(wǎng)絡(luò)圖片轉(zhuǎn)成輸入流以及將url轉(zhuǎn)成InputStream問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • java連接HBase,連接不上報(bào)錯can not resolve問題及解決

    java連接HBase,連接不上報(bào)錯can not resolve問題及解決

    這篇文章主要介紹了java連接HBase,連接不上報(bào)錯can not resolve問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Spring Boot集成Seata實(shí)現(xiàn)基于AT模式的分布式事務(wù)的解決方案

    Spring Boot集成Seata實(shí)現(xiàn)基于AT模式的分布式事務(wù)的解決方案

    Seata 是一款開源的分布式事務(wù)解決方案,致力于提供高性能和簡單易用的分布式事務(wù)服務(wù),這篇文章主要介紹了Spring Boot集成Seata實(shí)現(xiàn)基于AT模式的分布式事務(wù),需要的朋友可以參考下
    2024-08-08
  • 一篇文章帶你深入了解Java對象與Java類

    一篇文章帶你深入了解Java對象與Java類

    這篇文章主要給大家介紹了關(guān)于java中類和對象的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • spring如何加載配置多個配置文件

    spring如何加載配置多個配置文件

    這篇文章主要介紹了spring如何加載配置多個配置文件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Java實(shí)現(xiàn)身份證號碼驗(yàn)證源碼示例分享

    Java實(shí)現(xiàn)身份證號碼驗(yàn)證源碼示例分享

    本篇文章主要介紹了Java實(shí)現(xiàn)身份證號碼驗(yàn)證源碼示例分享,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10

最新評論

盐池县| 嘉兴市| 宝兴县| 尼勒克县| 浑源县| 白城市| 万荣县| 苍南县| 青海省| 聂荣县| 广宁县| 庆元县| 康平县| 淅川县| 津南区| 怀远县| 东乡| 宜宾市| 龙泉市| 聂荣县| 繁峙县| 永修县| 榆林市| 资溪县| 台北市| 淳安县| 揭东县| 保亭| 垦利县| 浠水县| 佛山市| 同德县| 府谷县| 普安县| 宝兴县| 资中县| 疏勒县| 波密县| 温泉县| 白玉县| 蕉岭县|