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

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

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

服務器之家 - 編程語言 - Java教程 - 以銀行取錢為例模擬Java多線程同步問題完整代碼

以銀行取錢為例模擬Java多線程同步問題完整代碼

2021-03-07 12:22李學凱 Java教程

這篇文章主要介紹了以銀行取錢為例模擬Java多線程同步問題完整代碼,具有一定借鑒價值,需要的朋友可以參考下。

簡單了解下在操作系統中進程和線程的區別:

  進程:每個進程都有獨立的代碼和數據空間(進程上下文),進程間的切換會有較大的開銷,一個進程包含1--n個線程。(進程是資源分配的最小單位)

  線程:同一類線程共享代碼和數據空間,每個線程有獨立的運行棧和程序計數器(PC),線程切換開銷小。(線程是cpu調度的最小單位)

  線程和進程一樣分為五個階段:創建、就緒、運行、阻塞、終止。

  多進程是指操作系統能同時運行多個任務(程序)。

  多線程是指在同一程序中有多個順序流在執行。首先存錢取錢的這個操作,應該是線程操作的,可以有很多的顧客,這意思就是得有多個線程,多個線程之間共同操作一個銀行,銀行的金額就需要同步。才能保證線程安全。

所以,下面就把這個代碼的實例放這,有不對的地方,還請指出來哈。因為有個老鐵問這個多線程的代碼。

首先是銀行,這個對象model的創建。

?
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
package com.lxk.threadTest.bank;
/**
 * 銀行model,一個總金額屬性。
 * <p>
 *
 * @author lxk on 2017/6/26
 */
public class Bank {
    /**
   * 給銀行個啟動資金,不然怎么干生意呢。
   */
    private int sum = 200;
    //這個從來不這么用,但也算是正確的一種加鎖的機制:同步代碼塊。
    //Object obj = new Object();
    /**
   * 存錢
   * 要是不加[synchronized--同步函數],則會出現多線程安全問題。
   */
    public synchronized void add(int n) {
        //synchronized (obj) {
        sum = sum + n;
        try {
            Thread.sleep(10);
        }
        catch (Exception ignore) {
        }
        //當存錢次數變多的時候,就可以發現,存錢的線程確實是2個在交替執行存錢這個動作的。
        System.out.println(Thread.currentThread().getName() + "...sum=" + sum);
        //}
    }
    /**
   * 取錢
   * 要是不加[synchronized--同步函數],則會出現多線程安全問題。
   */
    public synchronized void reduce(int n) {
        if (sum - n >= 0) {
            sum = sum - n;
        } else {
            System.out.println("bank's money is not enough !");
        }
        try {
            Thread.sleep(30);
        }
        catch (Exception ignore) {
        }
        //當存錢次數變多的時候,就可以發現,存錢的線程確實是2個在交替執行存錢這個動作的。
        System.out.println(Thread.currentThread().getName() + "...sum=" + sum);
    }
}

在代碼里面有存和取2個方法,這2個方法,以及一個總金額,里面有部分被注釋掉的代碼,那個是簡單易懂好理解的,多線程加鎖互斥,保證線程間同步的方法。

但是這個是不常用的方法,常用的就是使用synchronized這個關鍵字來修飾同步方法。

客戶對象的model

?
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
package com.lxk.threadTest.bank;
/**
 * 顧客,實現runnable()接口,多個人可以一起存錢
 *
 * @author lxk on 2017/6/26
 */
public class Customer implements Runnable {
    /**
   * 存錢類型
   */
    static final String TYPE_ADD = "add";
    /**
   * 取錢類型
   */
    static final String TYPE_REDUCE = "reduce";
    /**
   * 銀行
   */
    private Bank bank;
    /**
   * 對錢的操作類型,存錢or取錢
   */
    private String type;
    /**
   * 操作的次數,理論上是個正數
   */
    private int time;
    /**
   * 要存或者取多少錢
   */
    private int money;
    public Customer() {
    }
    public Customer(Bank bank, String type, int time, int money) {
        this.bank = bank;
        this.type = type;
        this.time = time;
        this.money = money;
    }
    @Override
      public void run() {
        for (int x = 0; x < time; x++) {
            if (TYPE_ADD.equals(type)) {
                bank.add(money);
            } else if (TYPE_REDUCE.equals(type)) {
                bank.reduce(money);
            }
        }
    }
}

客戶對象,因為可以很多個客戶同時訪問一個銀行,所以,這個存錢取錢的操作就用線程來實現。

屬性就構造方法傳值了。

main方法

?
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 com.lxk.threadTest.bank;
/**
 * 銀行存錢的多線程實例
 * <p>
 * 【需求:】
 * 銀行有一個金庫。
 * 有兩個儲戶分別存或者取n * 100。
 * 目的:該程序是否有安全問題,如果有,如何解決?
 * <p>
 * 【如何找問題:】
 * 1,明確哪些代碼是多線程運行代碼。
 * 2,明確共享數據。
 * 3,明確多線程運行代碼中哪些語句是操作共享數據的。
 *
 * @author lxk on 2017/6/26
 */
public class Main {
    public static void main(String[] args) {
        //一個銀行and多個客戶
        Bank bank = new Bank();
        int time = 10000;
        int money = 100;
        //這個客戶存錢
        Customer c1 = new Customer(bank, Customer.TYPE_ADD, time, money);
        //這個客戶取錢
        Customer c2 = new Customer(bank, Customer.TYPE_REDUCE, time, money);
        Thread t1 = new Thread(c1);
        Thread t2 = new Thread(c2);
        t1.start();
        t2.start();
    }
}

上述代碼實際運行效果如下圖。

以銀行取錢為例模擬Java多線程同步問題完整代碼

這個存取錢的次數要是小了,就可能會看到2個線程有先后順序,所以,這個次數咱整多點,然后,就看到如圖所示的情況,線程1是取錢的,線程0時存錢的,可以看到2個線程是互相交錯執行的,有存有取,沒有規律可言。

這個就保證了數據的同步了。

至于如何才能不同步,也就是異常的現象,

你可以把add方法的這個synchronized關鍵字去掉之后,把次數調小一點改成3次,sum的初始值給設置成0.你再試試代碼,

就會發現所謂的不同步現象。

以銀行取錢為例模擬Java多線程同步問題完整代碼

上圖的右邊就是不同步的結果,2個人每次存100,存三次,總數是不是得,100,200,300,400,500,600.得長。

但是,運行結果卻不是的,

這個時候,你再把synchronized給add方法加上去,就會出現左邊的圖的結果,這個就是正確的結果。

我是為了,有存有取,所以,就又加了個方法。代碼就變成上面的樣子啦。

差不多都是線程間同步的例子啦。

我就簡單記錄下代碼。用的時候,可以分分鐘就拿出來。

總結

以上就是本文關于以銀行取錢為例模擬Java多線程同步問題完整代碼的全部內容,希望對大家有所幫助。如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

原文鏈接:http://blog.csdn.net/qq_27093465/article/details/78637759

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 波多野结衣快播 | 国自产精品手机在线视频 | 日本捏胸吃奶视频免费 | 九九免费高清在线观看视频 | 亚洲精品色图 | 丝瓜秋葵番茄绿巨人在线观看 | 日本国产最新一区二区三区 | 午夜欧美精品久久久久久久 | 久久综合色超碰人人 | 人配人种视频xxxx | 欧美日韩高清观看一区二区 | 免费亚洲视频 | 日韩欧美在线看 | 97国产蝌蚪视频在线观看 | 羞羞漫画免费漫画页面在线看漫画秋蝉 | 日韩在线视精品在亚洲 | 国产免费成人在线视频 | oneday日本在线观看完整版 | 太粗 好紧 使劲舒服 | 国产精品成人麻豆专区 | 成人资源在线观看 | 国产绿帽 | 亚洲风情无码免费视频 | a∨在线观看 | 耽美肉文高h | 国内精品久久久久影院男同志 | 亚洲精品123区在线观看 | 91精品大神国产在线播放 | ipx-177绝对领域在线观看 | 成人在线小视频 | 东方影库四虎 | jiujiure精品| 1986葫芦兄弟全集免费观看第十集 | 亚洲日本中文字幕天堂网 | 国产午夜精品久久理论片小说 | 精品破处 | 欧美理论片手机在线观看片免费 | 亚洲视频99 | 免费370理论片中文字幕 | 欧美一级视频在线观看 | 污黄漫 |