0

Why usually threading samples put so many code in synchronized block. According to my understanding in following case synchronized is used just for locking b for wait and notify:

Main class ThreadA :

class ThreadA {
      public static void main(String [] args) {
         ThreadB b = new ThreadB();
         b.start();

         synchronized(b) {
            try {
               System.out.println("Waiting for b to complete...");

              b.wait();
           } catch (InterruptedException e) {}
           System.out.println("Total is: " + b.total);
           System.out.println(Thread.currentThread().getName());

        }
     }
  }

and class ThreadB:

class ThreadB extends Thread {   
     int total;     
     public void run() {
        synchronized(this) 
        {
           System.out.println();
           for(int i=0;i<100;i++) 
           {
               System.out.println(Thread.currentThread().getName());
              total += i;
           }
           notify();
        }
     }
  }

What will change if I put just wait and notify in synchronized block:

class ThreadA {
      public static void main(String [] args) {
         ThreadB b = new ThreadB();
         b.start();
            try {
               System.out.println("Waiting for b to complete...");

                synchronized(b) {   b.wait();}
           } catch (InterruptedException e) {}
           System.out.println("Total is: " + b.total);
           System.out.println(Thread.currentThread().getName());


     }
  }

3 Answers 3

3

According to my understanding in following case synchronized is used just for locking b for wait and notify

Your understanding is wrong.

synchronized is also used for:

  • Mutual exclusion, to ensure that only one thread executes code "guarded" by a particular monitor at a time
  • Ensuring memory access across threads is correct (that one thread sees changes made by another thread)

What will change if I put just wait and notify in synchronized block:

In this particular case, it will make a difference based on a race condition - in the original code, if the new thread starts executing before the synchronized block is reached in the original thread, it won't get as far as "Waiting for b to complete" until the second thread has finished... at which point it will block forever in wait.

Note that it's a really bad idea to wait on Thread monitors, as wait/notify is used internally by Thread.

In short, the example you've used is a bad one to start with in various ways - but synchronization is used for more than just wait/notify.

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

2 Comments

>Note that it's a really bad idea to wait on Thread monitors. But how I can deal in this particular case when I need wait for thread to finish job?
@user1501700: Use a different monitor instead of the Thread... or better yet, use Thread.join() as that's what it's there for. Personally I wouldn't extend Thread either - implement Runnable and pass an instance to the Thread constructor.
0

Please note that total += i is not an atomic operation in Java. So you have to sync also this construct.

You also have not to sync notify() and wait() because their locks are handled internally.

2 Comments

but in this particular case it is safe not to sync total +=i, because nobody will edit it and according code it will be read only after notify, when total will not be edited. I am wrong?
you mean I can write just 'b.wait();' instead of 'synchronized(b) { b.wait();}'?
0

Expanding on the answer by @sk2212, the increment operation is not atomic, but there is an equivalent atomic operation provided in high-level concurrency primitives.

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.