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

Java線程同步Lock同步鎖代碼示例

 更新時(shí)間:2017年11月14日 09:03:40   作者:超超boy  
這篇文章主要介紹了Java線程同步Lock同步鎖代碼示例,首先介紹了Java線程同步的原理,然后對(duì)lock同步鎖作了簡(jiǎn)要闡述,分享了代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。

java線程同步原理

java會(huì)為每個(gè)object對(duì)象分配一個(gè)monitor,當(dāng)某個(gè)對(duì)象的同步方法(synchronizedmethods)被多個(gè)線程調(diào)用時(shí),該對(duì)象的monitor將負(fù)責(zé)處理這些訪問(wèn)的并發(fā)獨(dú)占要求。

當(dāng)一個(gè)線程調(diào)用一個(gè)對(duì)象的同步方法時(shí),JVM會(huì)檢查該對(duì)象的monitor。如果monitor沒(méi)有被占用,那么這個(gè)線程就得到了monitor的占有權(quán),可以繼續(xù)執(zhí)行該對(duì)象的同步方法;如果monitor被其他線程所占用,那么該線程將被掛起,直到monitor被釋放。

當(dāng)線程退出同步方法調(diào)用時(shí),該線程會(huì)釋放monitor,這將允許其他等待的線程獲得monitor以使對(duì)同步方法的調(diào)用執(zhí)行下去。

注意:Java對(duì)象的monitor機(jī)制和傳統(tǒng)的臨界檢查代碼區(qū)技術(shù)不一樣。java的一個(gè)同步方法并不意味著同時(shí)只有一個(gè)線程獨(dú)占執(zhí)行,但臨界檢查代碼區(qū)技術(shù)確實(shí)會(huì)保證同步方法在一個(gè)時(shí)刻只被一個(gè)線程獨(dú)占執(zhí)行。Java的monitor機(jī)制的準(zhǔn)確含義是:任何時(shí)刻,對(duì)一個(gè)指定object對(duì)象的某同步方法只能由一個(gè)線程來(lái)調(diào)用。

java對(duì)象的monitor是跟隨object實(shí)例來(lái)使用的,而不是跟隨程序代碼。兩個(gè)線程可以同時(shí)執(zhí)行相同的同步方法,比如:一個(gè)類(lèi)的同步方法是xMethod(),有a,b兩個(gè)對(duì)象實(shí)例,一個(gè)線程執(zhí)行a.xMethod(),另一個(gè)線程執(zhí)行b.xMethod().互不沖突。

Lock-同步鎖

Lock是java5提供的一個(gè)強(qiáng)大的線程同步機(jī)制--通過(guò)顯示定義同步鎖對(duì)象來(lái)實(shí)現(xiàn)同步。Lock可以顯示的加鎖、解鎖。每次只能有一個(gè)線程對(duì)lock對(duì)象加鎖。

Lock有ReadLock、WriteLock、ReentrantLock(可重入鎖)

常用的就是ReentrantLock。代碼如下:

代碼邏輯:Account賬戶類(lèi),實(shí)現(xiàn)取錢(qián)的同步方法、DrawThread取錢(qián)的線程

Account:

package lock.reentrantlock2;
import java.util.concurrent.locks.*;
/**
 *賬戶類(lèi),需保持同步
 */
public class Account
{
  //定義鎖對(duì)象
  private final ReentrantLock lock = new ReentrantLock();
  private String accountNo;
  private double balance;
  public Account(){}
  public Account(String accountNo , double balance)
  {
    this.accountNo = accountNo;
    this.balance = balance;
  }
  public void setAccountNo(String accountNo)
  {
    this.accountNo = accountNo;
  }
  public String getAccountNo()
  {
     return this.accountNo;
  }
  public double getBalance()
  {
     return this.balance;
  }
  public void draw(double drawAmount)
  {
    lock.lock();
    try
    {
      //賬戶余額大于取錢(qián)數(shù)目
      if (balance >= drawAmount)
      {
        //吐出鈔票
        System.out.println(Thread.currentThread().getName() +
          "取錢(qián)成功!吐出鈔票:" + drawAmount);
        try
        {
          Thread.sleep(1);      
        }
        catch (InterruptedException ex)
        {
          ex.printStackTrace();
        }
        //修改余額
        balance -= drawAmount;
        System.out.println("\t余額為: " + balance);
      }
      else
      {
        System.out.println(Thread.currentThread().getName() +
          "取錢(qián)失敗!余額不足!");
      }     
    }
    finally
    {
      lock.unlock();
    }
  }
  public int hashCode()
  {
    return accountNo.hashCode();
  }
  public boolean equals(Object obj)
  {
    if (obj != null && obj.getClass() == Account.class)
    {
      Account target = (Account)obj;
      return target.getAccountNo().equals(accountNo);
    }
    return false;
  }
}

DrawThread:

package lock.reentrantlock2;
/**
 * 調(diào)用account取錢(qián)
 *
 */
public class DrawThread extends Thread
{
  //模擬用戶賬戶
  private Account account;
  //當(dāng)前取錢(qián)線程所希望取的錢(qián)數(shù)
  private double drawAmount;
  public DrawThread(String name , Account account ,
    double drawAmount)
  {
    super(name);
    this.account = account;
    this.drawAmount = drawAmount;
  }
  //當(dāng)多條線程修改同一個(gè)共享數(shù)據(jù)時(shí),將涉及到數(shù)據(jù)安全問(wèn)題。
  public void run()
  {
    account.draw(drawAmount);
  }
}

TestDraw:

package lock.reentrantlock2;
/**
 */
public class TestDraw
{
  public static void main(String[] args)
  {
    //創(chuàng)建一個(gè)賬戶
    Account acct = new Account("1234567" , 1000);
    //模擬兩個(gè)線程對(duì)同一個(gè)賬戶取錢(qián)
    new DrawThread("甲" , acct , 800).start();
    new DrawThread("乙" , acct , 800).start();
  }
}

運(yùn)行結(jié)果:

甲取錢(qián)成功!吐出鈔票:800.0 
余額為:200.0 
乙取錢(qián)失??!余額不足! 

使用Lock同步與同步方法很相似,都是“加鎖--修改公共變量--釋放鎖”的模式,代碼很容易看懂。兩個(gè)線程對(duì)應(yīng)一個(gè)Account對(duì)象,保證了兩個(gè)線程對(duì)應(yīng)一個(gè)lock對(duì)象,保證了同一時(shí)刻只有一個(gè)線程進(jìn)入臨界區(qū)。Lock還包含太容易Lock(),以及試圖獲取可中斷鎖的lockInterruptibly(),獲取超時(shí)失效鎖的tryLock(long,TimeUnit)等方法。

ReentrantLock鎖具有可重入性可以對(duì)已被加鎖的ReentrantLock鎖再次加鎖,線程每次調(diào)用lock()加鎖后,必須顯示的調(diào)用unlock來(lái)釋放鎖,有幾個(gè)lock就對(duì)應(yīng)幾個(gè)unlock。還有把unlock放在finally代碼塊中,Lock在發(fā)生異常時(shí)也是不釋放鎖的,所以在finally中釋放更安全。

總結(jié)

以上就是本文關(guān)于Java線程同步Lock同步鎖代碼示例的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:

創(chuàng)建并運(yùn)行一個(gè)java線程方法介紹

Java編程之多線程死鎖與線程間通信簡(jiǎn)單實(shí)現(xiàn)代碼

Java多線程編程小實(shí)例模擬停車(chē)場(chǎng)系統(tǒng)

有什么問(wèn)題可以隨時(shí)留言,小編會(huì)及時(shí)回復(fù)大家的。感謝朋友們對(duì)本站的支持!

相關(guān)文章

  • java17日期周期格式化處理方案

    java17日期周期格式化處理方案

    Java17引入了新的日期時(shí)間格式化模式B,用于表示一天中的時(shí)間段,如上午、下午、晚上等,該模式根據(jù)CLDR定義,在不同語(yǔ)言環(huán)境下,該模式的輸出結(jié)果會(huì)有所不同,本文給大家介紹java17日期周期格式化處理方案,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • 使用Java讀取Word文件的簡(jiǎn)單例子分享

    使用Java讀取Word文件的簡(jiǎn)單例子分享

    這篇文章主要介紹了使用Java讀取Word文件的簡(jiǎn)單例子分享,包括讀取word文件的表格數(shù)據(jù)的示例,需要的朋友可以參考下
    2015-10-10
  • 基于SpringBoot?Mock單元測(cè)試詳解

    基于SpringBoot?Mock單元測(cè)試詳解

    這篇文章主要介紹了基于SpringBoot?Mock單元測(cè)試詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java輸入數(shù)據(jù)的知識(shí)點(diǎn)整理

    Java輸入數(shù)據(jù)的知識(shí)點(diǎn)整理

    在本篇文章里小編給大家整理的是關(guān)于Java如何輸入數(shù)據(jù)的相關(guān)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友們學(xué)習(xí)參考下。
    2020-01-01
  • Java基礎(chǔ)之刪除文本文件中特定行的內(nèi)容

    Java基礎(chǔ)之刪除文本文件中特定行的內(nèi)容

    這篇文章主要介紹了Java基礎(chǔ)之刪除文本文件中特定行的內(nèi)容,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • spring boot2結(jié)合mybatis增刪改查的實(shí)現(xiàn)

    spring boot2結(jié)合mybatis增刪改查的實(shí)現(xiàn)

    這篇文章主要給大家介紹了關(guān)于spring boot2結(jié)合mybatis增刪改查的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用spring boot2具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • JVM:你知道為什么對(duì)象一定在堆中分配嗎

    JVM:你知道為什么對(duì)象一定在堆中分配嗎

    這篇文章主要介紹了jvm對(duì)象的創(chuàng)建和分配的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下,希望能夠給你帶來(lái)幫助
    2021-08-08
  • Java MongoDB數(shù)據(jù)庫(kù)連接方法梳理

    Java MongoDB數(shù)據(jù)庫(kù)連接方法梳理

    MongoDB作為一種介于關(guān)系型數(shù)據(jù)庫(kù)和非關(guān)系型數(shù)據(jù)庫(kù)之間的產(chǎn)品,它可以提供可擴(kuò)展的高性能的數(shù)據(jù)存儲(chǔ)解決方案,近些年來(lái)受到了開(kāi)發(fā)者的喜愛(ài)
    2022-08-08
  • SpringBoot如何啟動(dòng)自動(dòng)加載自定義模塊yml文件(PropertySourceFactory)

    SpringBoot如何啟動(dòng)自動(dòng)加載自定義模塊yml文件(PropertySourceFactory)

    這篇文章主要介紹了SpringBoot如何啟動(dòng)自動(dòng)加載自定義模塊yml文件(PropertySourceFactory),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 關(guān)于@Value注解取不到值的幾種情況

    關(guān)于@Value注解取不到值的幾種情況

    這篇文章主要介紹了關(guān)于@Value注解取不到值的幾種情況,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11

最新評(píng)論

青冈县| 安国市| 太谷县| 铜梁县| 呼玛县| 无棣县| 望谟县| 改则县| 南江县| 柞水县| 读书| 青海省| 左云县| 伊宁市| 翼城县| 洮南市| 长子县| 南川市| 新沂市| 临洮县| 乌鲁木齐县| 武义县| 沧源| 开江县| 兴化市| 双江| 厦门市| 普兰县| 晋城| 唐河县| 天津市| 平和县| 贵州省| 武川县| 宁海县| 清远市| 伊吾县| 四子王旗| 南漳县| 上思县| 静乐县|