Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Synchronized synchronizes all synchronized methods of a class among each other?

I've a question about synchronization in java. In the following Java program I dont get any output. But, if I remove the synchronized statement from the method IFoo.s() I'll get some output. It seems like the methods IFoo.setP() and IFoo.s() are synchronized among each other. But 'synchronized' should only prevent that two threads call the synchronized method at the same time, right?

package com.example.relectiontest;

import java.awt.Point;
import java.util.Random;

public class Main {

public static void main(String[] args) throws Exception{
    final IFoo f = new IFoo();
    Runnable r = new Runnable() {
        public void run() {
            Random r = new Random();
            int a = r.nextInt(5)+1;
            for(int i=0;i<1000000;++i){
                f.setP(a);
            }
        }
    };
    Runnable r2 = new Runnable() {
        public void run() {
            for(int i=0;i<1000000;++i){
                f.s();
            }
        }
    };
    Thread T1 = new Thread(r, "T1");
    Thread T2 = new Thread(r, "T2");
    Thread T3 = new Thread(r2, "T3");
    T3.start();
    T1.start();
    T2.start();
}

private static class IFoo{
    private Point p = new Point();

    public synchronized void setP(int a){
        //System.out.println("p1 "+Thread.currentThread());
        p.x = a;
        p.y = p.x;
        int x = p.x , y = p.y;
        if(x != y)
            System.out.println(Thread.currentThread()+"\t"+x+" "+y);
        //System.out.println("p2 "+Thread.currentThread());
    }

    public synchronized void s(){
        //System.out.println("s");
        p.x = 0;
    }
}
}

So, why I cant see any output?

regards

like image 865
user2224350 Avatar asked Jan 30 '26 12:01

user2224350


1 Answers

Because thanks to synchronization x != y will never be true.

In your unsynchronized version s() has the chance of setting p.x to 0 every once in a while (even though it's not synchronized properly).

In the synchronized version s() must wait until setP is finished (since they're both synchronized, sharing the implicit this lock), and thanks to the logic in setP the condition can not be true.

Your example is overly complex. You can write it out as follows (adding synchronized on both methods to see that nothing will be printed):

private static class IFoo {
    volatile int x = 0;
    public void setP(int a) {
        x = a;
        if(x != a)
            System.out.println("Someone changed x!");
    }

    public void s() {
        x = 0;
    }
}

Also note that static synchronized methods synchronize on the Class object since they have no this. Instance and static methods therefore won't lock each other unless you explicitly synchronize on a common lock.

like image 148
Kayaman Avatar answered Feb 01 '26 01:02

Kayaman