• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

simple synchronized question

 
Ranch Hand
Posts: 635
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I want to create an example to show why using of synchronized is necessary.

I write this code:



1-If I run this code, It sometimes show two "ERROR" and sometimes one, Why?

2-If I run this code without:


It does not show anything, Why?

3-If I run this code:


It does not show anything!

But If I run this code:



It shows this:

ERROR
ERROR



Why?What happened that it shows ERROR?
 
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
1-If I run this code, It sometimes show two "ERROR" and sometimes one, Why?

Since you are spawning two threads Mrxaccount and Mrsxaccount, both may run at any time. In your main() method,


which implies that two objects Mrxaccount and Mrsxaccount will start two threads and will call run method at any time without knowing the sequence of execution.
Consider the scenario below:
Scenario 1:
Step 1: Suppose Mrxaccount object calls run() method at line no. 3. It will deduct 100 from amount. Value of total = 100-100 = 0
Step 2: Now Mrxaccount object starts thread at line 1. It will call run method automatically which internally calls deduct() method. Since, total=0 here, 'else' statement will be executed and ERROR will be printed on screen.
Step 3: After printing ERROR, program will get terminated because of exit() method. So ERROR will be printed only one time.
Step 4: Remember here, other object Mrsxaccount didnt get turn to execute itself.

Scenario 2:
Step 1: Suppose, step 1 and 2 of scenario 1 is executed.
Step 2: Suppose, before the execution of Step 3, another object Mrsxaccount gets executed in the same manner Mrxaccount got executed till step 3. In that case, ERROR message will be printed by Mrsxaccount object and program termination will happen after that.

Here ERROR message you see will be twice.
 
agilemanoj kumar
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Answer to 2nd question:
2-If I run this code without:
1. Mrxaccount.run();
2. Mrsxaccount.run();


In your Account class, variable 'total' is declared as private. It means, two different objects will have two separate copies of instance variable total.
In main () method, you have created two different objects Mrxaccount and Mrsxaccount. These two object are calling run() method in different stacks. Variable total is not shared between these two objects.
Remember, Just calling Mrxaccount.run() and Mrsxaccount.run(), does not creates thread here. These are just simple two objects.
That s why, When Mrxaccount.run() gets called, total = 100-100 = 0
And when Mrsxaccount.run() gets called, total = 100 - 100 = 0 (here total will be 100 not 0)
So, you wont see any message here
 
agilemanoj kumar
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Your 3rd question is:
3-If I run this code:
1. public class Main {
2. public static void main(String[] args) {
3. Account Mrxaccount = new Account("Mrxaccount");
4. Account Mrsxaccount = new Account("Mrsxaccount");
5. //Mrxaccount.start();
6. //Mrsxaccount.start();
7. //Mrxaccount.run();
8. //Mrsxaccount.run();
9.
10. Mrsxaccount.deduct(100);
11. Mrxaccount.deduct(100);
12.
13. }
14.
15.
16. }

public class Main { public static void main(String[] args) { Account Mrxaccount = new Account("Mrxaccount"); Account Mrsxaccount = new Account("Mrsxaccount"); //Mrxaccount.start(); //Mrsxaccount.start(); //Mrxaccount.run(); //Mrsxaccount.run(); Mrsxaccount.deduct(100); Mrxaccount.deduct(100); } }

It does not show anything!


Answer to 3rd question:
Please see answer to 2nd question, my previous reply. Calling Mrxaccount.run() or Mrxaccount.deduct(100) method are same a like. They dont have to do anything with Threads.
 
agilemanoj kumar
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Your 4th question:

But If I run this code:
1. public class Main {
2. public static void main(String[] args) {
3. Account Mrxaccount = new Account("Mrxaccount");
4. Account Mrsxaccount = new Account("Mrsxaccount");
5. Mrxaccount.start();
6. Mrsxaccount.start();
7. //Mrxaccount.run();
8. //Mrsxaccount.run();
9.
10. Mrsxaccount.deduct(100);
11. Mrxaccount.deduct(100);
12.
13. }
14.
15.
16. }

public class Main { public static void main(String[] args) { Account Mrxaccount = new Account("Mrxaccount"); Account Mrsxaccount = new Account("Mrsxaccount"); Mrxaccount.start(); Mrsxaccount.start(); //Mrxaccount.run(); //Mrsxaccount.run(); Mrsxaccount.deduct(100); Mrxaccount.deduct(100); } }

It shows this:

ERROR
ERROR



Why?What happened that it shows ERROR?


Answer to your 4th question:
Put breakpoints at and and run your program in debug mode. You will see only one ERROR.
PS: It is hard to predict running sequence of threads. In your 4th question, Two threads are spawned and most of the time (say 99%) second thread is calling

System.exit(0);

not first thread. That's why you are seeing two ERROR almost all the time. Here, after execution of 'System.out.println("ERROR");' by first thread, second thread calls 'System.out.println("ERROR");' and 'System.exit(0);' almost all the time.
 
abalfazl hossein
Ranch Hand
Posts: 635
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
First of all, Thank you very much for your nice explanation.

As I understand ,In this case, It is not necessary to use Synchronized block.Because we have different objects,
In fact I wanted to change that code to show how Synchronized block is necessary. Could show me how can I do that? How can I change that code in order to show how Synchronized block is necessary?
 
abalfazl hossein
Ranch Hand
Posts: 635
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I saw this example in JAVA threads book.



and I change it. But now I understand because total is private it does not need to be synchronized:


 
agilemanoj kumar
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, you are right...
 
abalfazl hossein
Ranch Hand
Posts: 635
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think that if Runnable interface used instead extend thread class, Then it makes sense that why it is necessary to use synchronize.

reply
    Bookmark Topic Watch Topic
  • New Topic