简体   繁体   中英

More threads to synchronized method of same instance

What happens when 1000 requests(each Httprequest as one thread) came to server that calls deposit method of Trust object.

I have written code like this which works fine, but what is the case if deposit amount had long logic that makes other threads in waiting state.

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();
        }
    }
}

In a case deposit amount method has long logic, Please tell me suppose when 1000 requests came at one instance to deposit amount into trust. Will the remaining 999 threads will get blocked till the first thread deopists amount. What about the last thread, the user needs to wait till that time for the response.

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

Yes. The first thread will enter the deposit method. Any other threads that want to do the same will enter a blocked state until the resource becomes free.

Yes, all other threads using the synchronised "deposit" method on Trust have to wait for the first caller to finish it's method call on deposit. That's a little tricky with your shared state "Trust"...

You should have a separated thread... This thread a.) gives other threads the opportunity to add "request for work" (a synchronised method, which just puts the requests in a queue) and a method within this thread working on that queue... With that you would have decoupled the processes of need to wait for the whole processing to be finished (because the threads only need to wait until the request has been put to the queue).

The threads will call deposit() one at a time. Thus the 1000th request will block until the other 999 have finished.

There are two ways to improve performance:

  1. Make the operations that are performed inside the synchronized block as quick as possible.
  2. Use a non-blocking algorithm .

The latter could be implemented using 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);
    }
}

Note that, even though this implementation is correct in terms of updating the account, the output strings could be printed out of order.

Also see Amdahl's Law .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM