一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

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

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - JAVA教程 - Java線程同步Lock同步鎖代碼示例

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

2021-02-04 11:30超超boy JAVA教程

這篇文章主要介紹了Java線程同步Lock同步鎖代碼示例,首先介紹了Java線程同步的原理,然后對lock同步鎖作了簡要闡述,分享了代碼示例,具有一定參考價值,需要的朋友可以了解下。

java線程同步原理

java會為每個object對象分配一個monitor,當某個對象的同步方法(synchronizedmethods)被多個線程調用時,該對象的monitor將負責處理這些訪問的并發獨占要求。

當一個線程調用一個對象的同步方法時,JVM會檢查該對象的monitor。如果monitor沒有被占用,那么這個線程就得到了monitor的占有權,可以繼續執行該對象的同步方法;如果monitor被其他線程所占用,那么該線程將被掛起,直到monitor被釋放。

當線程退出同步方法調用時,該線程會釋放monitor,這將允許其他等待的線程獲得monitor以使對同步方法的調用執行下去。

注意:Java對象的monitor機制和傳統的臨界檢查代碼區技術不一樣。java的一個同步方法并不意味著同時只有一個線程獨占執行,但臨界檢查代碼區技術確實會保證同步方法在一個時刻只被一個線程獨占執行。Java的monitor機制的準確含義是:任何時刻,對一個指定object對象的某同步方法只能由一個線程來調用。

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

Lock-同步鎖

Lock是java5提供的一個強大的線程同步機制--通過顯示定義同步鎖對象來實現同步。Lock可以顯示的加鎖、解鎖。每次只能有一個線程對lock對象加鎖。

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

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

代碼邏輯:Account賬戶類,實現取錢的同步方法、DrawThread取錢的線程

Account:

?
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package lock.reentrantlock2;
import java.util.concurrent.locks.*;
/**
 *賬戶類,需保持同步
 */
public class Account
{
  //定義鎖對象
  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
    {
      //賬戶余額大于取錢數目
      if (balance >= drawAmount)
      {
        //吐出鈔票
        System.out.println(Thread.currentThread().getName() +
          "取錢成功!吐出鈔票:" + drawAmount);
        try
        {
          Thread.sleep(1);     
        }
        catch (InterruptedException ex)
        {
          ex.printStackTrace();
        }
        //修改余額
        balance -= drawAmount;
        System.out.println("\t余額為: " + balance);
      }
      else
      {
        System.out.println(Thread.currentThread().getName() +
          "取錢失敗!余額不足!");
      }    
    }
    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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package lock.reentrantlock2;
/**
 * 調用account取錢
 *
 */
public class DrawThread extends Thread
{
  //模擬用戶賬戶
  private Account account;
  //當前取錢線程所希望取的錢數
  private double drawAmount;
  public DrawThread(String name , Account account ,
    double drawAmount)
  {
    super(name);
    this.account = account;
    this.drawAmount = drawAmount;
  }
  //當多條線程修改同一個共享數據時,將涉及到數據安全問題。
  public void run()
  {
    account.draw(drawAmount);
  }
}

TestDraw:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package lock.reentrantlock2;
/**
 */
public class TestDraw
{
  public static void main(String[] args)
  {
    //創建一個賬戶
    Account acct = new Account("1234567" , 1000);
    //模擬兩個線程對同一個賬戶取錢
    new DrawThread("甲" , acct , 800).start();
    new DrawThread("乙" , acct , 800).start();
  }
}

運行結果:

甲取錢成功!吐出鈔票:800.0 
余額為:200.0 
乙取錢失敗!余額不足! 

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

ReentrantLock鎖具有可重入性可以對已被加鎖的ReentrantLock鎖再次加鎖,線程每次調用lock()加鎖后,必須顯示的調用unlock來釋放鎖,有幾個lock就對應幾個unlock。還有把unlock放在finally代碼塊中,Lock在發生異常時也是不釋放鎖的,所以在finally中釋放更安全。

總結

以上就是本文關于Java線程同步Lock同步鎖代碼示例的全部內容,希望對大家有所幫助。有什么問題可以隨時留言,小編會及時回復大家的。感謝朋友們對本站的支持!

原文鏈接:http://www.cnblogs.com/jycboy/p/5623113.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91视频综合网 | 99视频九九精品视频在线观看 | 日本暖暖在线视频 | 五月天婷婷精品免费视频 | 無码一区中文字幕少妇熟女网站 | 欧美日韩亚洲国内综合网俺 | 99综合在线| 国产精品天天看特色大片不卡 | 四虎影院在线免费观看 | 日产一区二区 | 亚洲精品久久玖玖玖玖 | 国产成人精品1024在线 | 国产精品对白刺激久久久 | 国自产精品手机在线视频 | 亚洲成在人线视频 | 亚洲精品久久久打桩机 | 亚洲视频久久 | 国产在线精品香蕉综合网一区 | 亚欧成人一区二区 | 国产一区二 | 2019亚洲男人天堂 | 国产91无毒不卡在线观看 | 日韩视频一区 | 99久久久久久久 | 国色天香论坛社区在线视频 | 日本强不卡在线观看 | 91视频免费观看网站 | 免费刷10000名片赞网站 | 日产精品一二三四区国产 | 日本欧美一二三区色视频 | 国士李风起全文在线阅读 | 亚洲国产精品久久丫 | 毛片免费的 | a性片| 冰雪奇缘1完整版免费观看 变形金刚第一部 | 91久久精品国产亚洲 | 果冻传媒天美传媒乌鸦传媒 | 4虎tv| 国产成人精品综合在线观看 | 女黑人尺寸bbb | 久久精品18 |