1

I am trying to grasp the concept of synchronized methods in Java, but encountered the behavior that seems confusing, at least to me; In the code:

public class parallelUpdate
{
    public static void main(String[] args)
    {
        Ob ob = new Ob();
        new Thread(ob).start();
        new Thread(ob).start();
    }
}

class Ob implements Runnable
{
    static int cnt = 0;

    private synchronized void inc()
    {
        cnt++;
    }

    @Override
    public void run()
    {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread());
            inc();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

... incrementing is performed in parallel by both treads:

Thread[Thread-0,5,main]
Thread[Thread-1,5,main]
Thread[Thread-0,5,main]
Thread[Thread-1,5,main]
Thread[Thread-1,5,main]
Thread[Thread-0,5,main]
Thread[Thread-0,5,main]
Thread[Thread-1,5,main]

I expected that the use of synchronized for the inc() method would yield sequential incrementing, like:

Thread[Thread-0,5,main]
Thread[Thread-0,5,main]
Thread[Thread-0,5,main]
Thread[Thread-0,5,main]
Thread[Thread-0,5,main]
Thread[Thread-1,5,main]
Thread[Thread-1,5,main]
Thread[Thread-1,5,main]
Thread[Thread-1,5,main]
Thread[Thread-1,5,main]

What is wrong with my code?

Sean Bright
  • 118,630
  • 17
  • 138
  • 146
Konstantin
  • 127
  • 5

3 Answers3

0

This happens because Thread Scheduler decides what thread to run and there is no particular order in which it picks a thread. You can set a priority on a thread, but again it's up to scheduler to pick it or not. You can ask scheduler to run a particular thread, but not force it. Synchronising a method guaranties that method is only run by one thread at a time. I would also advice to check Thread Executers API which provides cleaner way to create, maintain and destroy a thread. Here is a useful link on threads in java: http://winterbe.com/posts/2015/04/07/java8-concurrency-tutorial-thread-executor-examples/

GarRudo
  • 158
  • 1
  • 10
0

Pleas find the correct Code:-

 public class parallelUpdate {
        public static void main(String[] args) {
            Ob ob = new Ob();
            new Thread(ob).start();
            new Thread(ob).start();

        }
    }


    class Ob implements Runnable {
        static int cnt = 0;
        private synchronized void inc() {
              for (int i = 0; i < 5; i++) {
                  System.out.println(Thread.currentThread());
                  cnt++;
                  try {
                      Thread.sleep(100);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              } 
        }
        @Override
        public void run() {
          inc();
        }
    }

Explanation against your code :-

you are making inc(); method as a synchronized but their is no synchronized for **for loop** so your two treads enters and perform the inc(); synchronized operation.

Hasnain Ali Bohra
  • 2,130
  • 2
  • 11
  • 25
0

If thread 2 start after thread 1 then a better solution is to use a join method, that means the program will want until thread 1 finish to start thread 2.

how wait for a thread to finish...

public static void main(String[] args) {
        Ob ob = new Ob();
        Thread myFirstThread = new Thread(ob);
        myFirstThread.start();

        try {
            myFirstThread.join();
        } catch (InterruptedException e) {

            e.printStackTrace();
        }   

        Thread mySecondThread = new Thread(ob);
        mySecondThread.start();

    }

Go to java documentation to clarify how syncrhonized methods works Synchronized Methos

  • First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
  • Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
Daniel C.
  • 5,418
  • 3
  • 23
  • 26