Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the synchronized method not accessed synchronously in this multithreaded program?

I've wrote some multithreading code in java and synchronized method that changed variable, but it doesn't synchronized my code, I still get random values. There is my code:

public class Main {
    public static void main(String[] args) throws Exception {
        Resource.i = 5;
        MyThread myThread = new MyThread();
        myThread.setName("one");
        MyThread myThread2 = new MyThread();
        myThread.start();
        myThread2.start();
        myThread.join();
        myThread2.join();
        System.out.println(Resource.i);
    }
}
class MyThread extends Thread {
    @Override
    public void run() {
        synMethod();
    }

    private synchronized void synMethod() {
        int i = Resource.i;
        if(Thread.currentThread().getName().equals("one")) {
            Thread.yield();
        }
        i++;
        Resource.i = i;
    }
}

class Resource {
    static int i;
}

Sometimes I get 7, sometimes 6, but I've synchronized synMethod, as I understand no thread should go at this method while some other thread executing this, so operations should be atomic, but they are not, and I can't understand why? Could you please explain it to me, and answer - how can I fix it?

like image 487
user769552 Avatar asked Aug 14 '16 06:08

user769552


1 Answers

Adding the synchronized method is like synchronizing on this. Since you have two different instances of threads, they don't lock each other out, and this synchronization doesn't really do anything.

In order for synchronization to take effect, you should synchronize on some shared resource. In your example, Resource.class could by a good choice:

private void synMethod() { // Not defined as synchronized
    // Synchronization done here:
    synchronized (Resource.class) {
        int i = Resource.i;
        if (Thread.currentThread().getName().equals("one")) {
            Thread.yield();
        }
        i++;
        Resource.i = i;
    }
}
like image 108
Mureinik Avatar answered Oct 09 '22 10:10

Mureinik