0

I am trying to see how multithreading(particularly with synchronized keyword) works.In this example I want the second thread abc1 to start executing after thread abc. So I've used synchronized keyword in run function.But the output line which says:

Initial balance in this thread is 10000
Initial balance in this thread is 10000

is what concerns me.Because the initial balance should be "-243000" as indicated in output line

Final balance after intial -243000 is 59049000

because the abc1 thread should wait for abc due to synchronized keyword. Primarily , I want the threads to behave as if I write

abc.start
abc.join()
abc1.start()
abc1.join()

Here is my source code:

class parallel extends Thread{
    account a;
    public parallel(account a) {
        this.a=a;
    }
    public synchronized void run() {
        
        synchronized(this) {
            System.out.println("Initial balance in this thread is "+a.amount);
            long duplicate=a.amount;
            boolean flag=true;
            //System.out.println("Transaction inititated");
            for(int i=0;i<10;i++) {
                if(flag==true) {
                    //System.out.println("Deducting "+amount+"Rs from your account");
                    a.amount-=a.amount*2;
                }
                else {
                    //System.out.println("Depositing "+amount+"Rs from your account");
                    a.amount+=a.amount*2;
                }
                flag=!flag;
            }
            System.out.println("Final balance after intial "+duplicate+" is "+a.amount);
            syncro.amount=a.amount;
        }
        
    }   
    
}
class account{
    public account(long rupe) {
        amount=rupe;
    }
    long amount;
}
public class syncro {
    static long amount;
    public static void main(String[] args) throws InterruptedException{
        
        
        //for(int i=0;i<10;i++) {
            account ramesh=new account(1000);
            parallel abc=new parallel(ramesh);
            parallel abc1=new parallel(ramesh);
            
            abc.start();
            //abc.join();
            abc1.start();
            //abc1.join();
            
        //}
        //awaitTermination();
        //Thread.sleep(4000);
            boolean ab=true;
            long cd=1000;
            for(int i=0;i<10;i++) {
                if(ab==true) {
                    //System.out.println("Deducting "+ab+"Rs from your account");
                    cd-=cd*2;
                }
                else {
                    //System.out.println("Depositing "+a+"Rs from your account");
                    cd+=cd*2;
                }
                ab=!ab;
            }
        //System.out.println("Final amount by multithreading is "+);
        
        System.out.println("Final amount after serial order is "+cd);


    }

}

2 Answers 2

1

You are mixing the creating of your own threads with the use of synchronized. Also, using synchronized(this) within a synchronized method is doing the same thing twice.

Synchronized is NOT about starting threads. It is about allowing only one thread to enter a certain block of code at a time.

Sign up to request clarification or add additional context in comments.

3 Comments

So, in reality two different threads are executing so synchronized keyword is not making a difference as they are executing their own run methods.Am I correct ?
Yes, you are right. Synchronized allows only one thread to enter a block of code (per instance for instance methods and per class for static methods). And you actually have 2 instances.
btw: making the run-method of Thread synchronized pretty much destroys the Thread-concept and should be avoided - even just for an example.
1

Every object you create has a hidden field that you cannot read, but it does exist. It is of type Thread and it is called owner.

The synchronized keyword interacts with this hidden field.

synchronized (object) {
   code();
}

means the following:

  1. If object.owner == Thread.currentThread(), then just keep going and increment a counter.
  2. If object.owner == null, then run object.owner = Thread.currentThread(), set that counter to 1, and keep going.
  3. Otherwise (So, object.owner is some other thread), stop, freeze the thread, and wait around until the owner is set to null, and then we can go to option #2 instead.
  4. Once we're in, run code(). When we get to the closing brace, decrement the counter. If it is 0, run object.owner = null.
  5. Furthermore, all the above is done atomically - it is not possible for 2 threads to get into a race condition doing all this stuff. For example, if 2 threads are waiting for owner to become unset again, only one will 'get it', and the other will continue waiting. (Which one gets it? A VM impl is free to choose whatever it wants; you should assume it is arbitrary but unfair. Don't write code that depends on a certain choice, in other words).
  6. A method that is keyworded with synchronized is just syntax sugar for wrapping ALL the code inside it in synchronized(this) for instance methods and synchronized(MyClass.this) for static methods.

Note that synchronized therefore only interacts with other synchronized blocks, and only those blocks for which the object in the parentheses is the exact same obj reference, otherwise none of this does anything. It certainly doesn't start threads! All synchronized does is potentially pause threads.

In your code, you've put ALL the run code in one gigantic synchronized block, synchronizing on your thread instance. As a general rule, when you synchronize on anything, it's public API - other code can synchronize on the same thing and affect you. Just like we don't generally write public fields in java, you should not lock on public things, and this is usually public (as in, code you don't control can hold a reference to you). So don't do that unless you're willing to spec out in your docs how your locking behaviours are set up. Instead, make an internal private final field, call it lock, and use that (private final Object lock = new Object();).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.