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) 在銀行賬戶的存款(
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