簡體   English   中英

更多線程可以同步同一實例的方法

[英]More threads to synchronized method of same instance

當1000個請求(每個Httprequest作為一個線程)到達服務器並調用Trust對象的deposit方法時,會發生什么情況。

我已經寫了這樣的代碼,可以很好地工作,但是如果存入金額具有較長的邏輯,這會使其他線程處於等待狀態,該怎么辦?

class Trust {
    private int amount;
    public synchronized void deposit(int amount) {
        this.amount += amount;
        System.out.println(Thread.currentThread().getName() + "; Amount " +this.amount);
    }
}

class DepositAmount implements Runnable {
    Trust obj;
    private int amount;

    DepositAmount(Trust obj, int amount) {
        this.obj = obj;
        this.amount += amount;
    }
    public void run() {
        obj.deposit(amount);
    }
}

public class Bank {//CustomerToTrust {
    public static void main(String args[]) {
        System.out.println("Naga");
        //amt.nextInt(5000)
        Trust obj = new Trust();
        for(int i =0; i< 100 ; i++) {
            Random amt = new Random();
            new Thread(new DepositAmount(obj, 100)).start();
        }
    }
}

如果存入金額的方法邏輯很長,請告訴我,假設一次有1000個請求將存入金額信任。 剩下的999個線程是否會被阻塞,直到第一個線程不再使用該線程。 關於最后一個線程,用戶需要等到那個時間才能得到響應。

“剩余的999個線程將被阻塞,直到第一個線程的操作員數量達到為止”

是。 第一個線程將進入存款方法。 任何其他想要執行此操作的線程都將進入阻塞狀態,直到資源可用。

是的,在Trust上使用同步的“ deposit”方法的所有其他線程必須等待第一個調用方完成其對存款的方法調用。 與您的共享狀態“信任”有點棘手...

您應該有一個單獨的線程...該線程a。)使其他線程有機會添加“工作請求”(同步方法,該方法將請求放入隊列中),並且該線程中的方法可以對該隊列進行工作...這樣一來,您便可以將需要等待整個處理完成的過程分離開來(因為線程只需要等待,直到將請求放入隊列中即可)。

線程將一次調用一次deposit() 因此,第1000個請求將被阻塞,直到另一個999完成為止。

有兩種提高性能的方法:

  1. 使在synchronized塊內執行的操作盡可能快。
  2. 使用非阻塞算法

后者可以使用AtomicInteger實現:

class Trust {
    private AtomicInteger balance = new AtomicInteger(0);
    public void deposit(int amount) {
        int newBalance = this.balance.addAndGet(amount);
        System.out.println(Thread.currentThread().getName() +
                           "; Balance " + newBalance);
    }
}

請注意,即使此實現在更新帳戶方面是正確的,也可能會無序打印輸出字符串。

另請參閱阿姆達爾定律

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM