1. 程式人生 > >Java例項說明 100個執行緒同時向一個銀行賬戶中存入1元錢,在沒有使用同步機制和使用同步機制情況下的執行情況

Java例項說明 100個執行緒同時向一個銀行賬戶中存入1元錢,在沒有使用同步機制和使用同步機制情況下的執行情況

銀行賬戶類:

public class Account {
private double balance; // 賬戶餘額
public void deposit(double money) {
double newBalance = balance + money;
try {
Thread.sleep(10); // 模擬此業務需要一段處理時間
} catch (InterruptedException ex) {
ex.printStackTrace();
}
balance = newBalance;
}
public double getBalance() {
return balance;
}
}

存錢執行緒類:

public class AddMoneyThread implements Runnable {
private Account account; // 存入賬戶
private double money; // 存入金額
public AddMoneyThread(Account account, double money) {
this.account = account;
this.money = money;
}
@Override
public void run() {
account.deposit(money);
}
}

測試類:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test01 {
public static void main(String[] args) {
Account account = new Account();
ExecutorService service = Executors.newFixedThreadPool(100);
for (int i = 1; i <= 100; i++) {
service.execute(new AddMoneyThread(account, 1));
}
service.shutdown();
while (!service.isTerminated()) {
}
System.out.println("賬戶餘額: " + account.getBalance());
}
}

執行結果:  賬戶餘額: 2.0

說明:

在 沒有同步的情況下,執行結果通常是顯示賬戶餘額在10元以下,出現這種狀況的原因是:

    當一個執行緒A試圖存入1元的時候,另外一個執行緒B也能夠進入存款的方法中,執行緒B讀取到的賬戶餘額仍然是執行緒A存入1元錢之前的賬戶餘額,因此也是在原來的餘額0上面做了加1元的操作,同理執行緒C也會做類似的事情,所以最後100個執行緒執行結束時,本來期望賬戶餘額為100元,但實際得到的通常在10元以下。

     解決這個問題的辦法就是同步,當一個執行緒對銀行賬戶存錢時,需要將此賬戶鎖定,待其操作完成後才允許其他的執行緒進行操作,程式碼有如下幾種調整方案:

1) 在銀行賬戶的存款(

deposit)方法上同步(synchronized)關鍵字

public synchronized void deposit(double money) 

執行結果:賬戶餘額: 100.0

2) 線上程呼叫存款方法時對銀行賬戶進行同步

    @Override

    public void run() {

synchronized (account) {

            account.deposit(money);

        }

    }

執行結果:賬戶餘額: 100.0

3) 通過JDK 1.5顯示的鎖機制,為每個銀行賬戶建立一個鎖物件,在存款操作進行加鎖和解鎖的操作

public class Account {

private Lock accountLock = new ReentrantLock();

    private double balance; // 賬戶餘額

    public void deposit(double money) {

accountLock.lock();

        try {

            double newBalance = balance + money;

            try {

                Thread.sleep(10); // 模擬此業務需要一段處理時間

            }

            catch (InterruptedException ex) {

                ex.printStackTrace();

            }

            balance = newBalance;

        }

        finally {

  accountLock.unlock();

        }

    }

    public double getBalance() {

        return balance;

    }

}

執行結果:賬戶餘額: 100.0

按照上述三種方式對程式碼進行修改後,重新執行測試程式碼Test01,將看到最終的賬戶餘額為100元。

相關推薦

Java例項說明 100執行同時一個銀行賬戶存入1沒有使用同步機制使用同步機制情況執行情況

銀行賬戶類: public class Account {private double balance; // 賬戶餘額public void deposit(double money) {double newBalance = balance + money;try {T

100線程同時一個銀行賬戶存入1

事情 調整 ice r12 同步機制 狀況 private nta tst 下面的例子演示了100個線程同時向一個銀行賬戶中存入1元錢,在沒有使用同步機制和使用同步機制情況下的執行情況。 銀行賬戶類: 1 2 3 4 5 6 7 8 9 10 11 12 1

關於Socket通訊執行同時一個服務埠傳送資料時的注意點

近幾天在開發的程式裡面有相關模組使用到了Socket通訊,其中存在多個類似功能的模組,這些模組可能出現在同一時間段向一個服務端埠傳送訊息的情況,剛開始使用一個socket去通訊,結果發現異常頻繁出現.(事實上,當傳送間隔很長,比如每200ms才會有一次傳送,那麼兩個執行緒之

JAVA執行之兩執行同時一個檔案

1.多執行緒        執行緒是程式執行流的最小單元。是程序中的一個實體,是被系統獨立排程和分派的基本單位,執行緒自己不擁有系統資源,只擁有一點兒在執行中必不可少的資源,但它可與同屬一個程序的其它執行緒共享程序所擁有的全部資源。一個執行緒可以建立和撤消另一個執行緒,同一程序中的多個執行緒之間可以併發執行

執行同時呼叫一個函式會出現什麼情況?

from: https://www.cnblogs.com/silentNight/p/5468805.html 最近在研究多執行緒,然後突然想到如果兩個執行緒同時訪問一個函式的話,要不要加鎖呢,加鎖怎麼加,不加又怎樣這樣的問題..然後去網上找了些帖子學習學習......

Linux程序或執行同時一個檔案進行寫操作

標頭檔案 #include<sys/file.h> 定義函式 int flock(int fd,int operation); 函式說明 flock()會依引數operation所指定的方式對引數fd所指的檔案做各種鎖定或解除鎖定的動作。此函式只能鎖定整個檔案,無法鎖定檔案的某一區域。 引數ope

單例模式執行同時訪問一個例項物件問題的處理加lock .

多執行緒同時訪問一個例項物件時, 可以給程序加一把鎖來處理。lock是確保當一個執行緒位於程式碼的臨界區時,另一個執行緒不進入臨界區。如果其他執行緒試圖進入鎖定的程式碼,則它將一直等待(即被阻止),直到該物件被釋放。 public class Singleton {    

【本人禿頂程式設計師】多執行:為什麼在while迴圈加入System.out.println執行可以停止

在論壇看到這樣一個程式碼: public class StopThread { private static boolean stopRequested; public static void main(String[] args) throws InterruptedE

執行:為什麼在while迴圈加入System.out.println執行可以停止

在論壇看到這樣一個程式碼: public class StopThread { private static boolean stopRequested; public static void main(String[] args) throws InterruptedE

java執行同時呼叫同一個靜態方法的問題

我的原來程式是這樣設計的,對於一些常用的方法,都用靜態方法來實現,在多執行緒程式中直接呼叫,靜態方法由於沒有使用靜態變數,所以沒有進行執行緒同步。 類似以下程式: class ThreadI { public static void main(String[] arg) {

java執行同時執行是怎麼變化的

線上程執行中,兩個執行緒同時執行的情況是很平常的,下面我用一個案例來說明一下兩個執行緒同時執行時,執行緒狀態的變化情況: 程式碼如下: /*  * 功能:兩個執行緒同時執行是如何變化的  * 作者:zyj0813  * 案例:編寫一個程式,該程式可以接受一個整數n,建立兩個

互斥鎖——多執行同時搶一把鎖出現的問題與處理方式

1、執行緒鎖的介紹 1.1 建立互斥鎖:        (1) 靜態互斥鎖初始化:pthread_mutex_t mutex_x= PTHREAD_MUTEX_INITIALIZER;                     此句建立鎖後,可以直接使用 pthread_

執行同時執行每個執行分別打印出自己的名字

public class ThreadName extends Thread{public void run(){System.out.println("執行緒:"+this.getName());//列印執行緒名字}public static void main(Stri

Java執行同時執行

    我們建立三個任務與三個執行緒,讓三個執行緒啟動,同時執行三個任務。     任務類必須實現 Runable 介面,而 Runable 介面只包含一個 run 方法。需要實現 這個方法來告訴系統

執行間無需特別的手段進行通訊因為執行間可以共享資料結構也就是一個全域性變數可以被兩執行同時使用不過要注意的是執行間需要做好同步

     執行緒間無需特別的手段進行通訊,因為執行緒間可以共享資料結構,也就是一個全域性變數可以被兩個執行緒同時使用。不過要注意的是執行緒間需要做好同步,一般用mutex。可以參考一些比較新的UNIX/Linux程式設計的書,都會提到Posix執行緒程式設計,比如《UNIX

面試題之----寫函式來解決多執行同時讀寫一個檔案的問題

一般的方案: //fopen():開啟檔案或者 URL,返回resource型別資料 。 $fp = fopen('./tmp/lock.txt', 'a+'); if (flock($fp, LOCK_EX)) {//取得獨佔鎖定 fwrite($fp, "Write something h

關於Spring容器定時器到時執行會出現兩執行同時執行的問題

最近公司有一個小需求,是需要定時去從某一個視訊供應商下載視訊檔案,問題很簡單,直接使用quartz,編寫相應的定時器程式碼,同時配置相應的定時器時間,但是在定時執行之後會出現兩個執行緒同時執行定時任務的問題,並且這兩個執行緒併發執行,從而一直影響到視訊檔案下載。

使用BlockingQueue執行同時處理同一型別的多資源

如果是單執行緒處理一批事情,例如,有16個日誌需要處理,各個日誌之間是獨立的,假設處理每個的時間是1秒, 一共需要處理16秒才能處理完。 現在使用多執行緒來加速處理時間,思路: 建立4個執行緒,每個執行緒從一個任務列表中獲取一個任務,進行處理,處理完後,再獲取一個,直到任務

java執行工具類可用該多執行同時處理相同且數量多的任務

package zrh4; public class ThreadModel {private static int maxThread = 4;protected static int currentThread = 0;private static ThreadMode

使用執行同時讀取兩檔案並寫出執行相關問題

使用執行緒同時讀取兩個檔案並寫出 1,建立工具類(載入檔案,讀取內容,寫出內容等方法) reader = new BufferedReader(new Reader(new File(file)); 檔案會有中文亂碼, reader = new BufferedRea