更多线程同步到同一实例的方法

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 个线程是否会被阻塞,直到第一个线程 deopists 数量。最后一个线程呢,用户需要等到那个时候才有响应。

"Will the remaining 999 threads will get blocked till the first thread deopists amount"

是的。第一个线程会进入 deposit 方法。 任何其他想要执行相同操作的线程都将进入阻塞状态,直到资源空闲为止。

是的,在 Trust 上使用同步 "deposit" 方法的所有其他线程都必须等待第一个调用者完成它对存款的方法调用。 你的共享状态有点棘手 "Trust"...

你应该有一个单独的线程...这个线程 a.) 让其他线程有机会添加 "request for work"(一个同步方法,它只是将请求放入队列中)和这个线程中的一个方法在该队列上工作的线程......这样你就可以解耦需要等待整个处理完成的过程(因为线程只需要等到请求被放入队列)。

线程将一次调用一个 deposit()。因此第 1000 个请求将阻塞,直到其他 999 个请求完成。

有两种提高性能的方法:

  1. 使在 synchronized 块内执行的操作尽可能快。
  2. 使用 non-blocking algorithm.

后者可以使用 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);
    }
}

请注意,尽管此实现在更新帐户方面是正确的,但输出字符串可能会乱序打印。

另见 Amdahl's Law