1

I was reading a threading tutorial that’s originally from (I believe) the IBM developerworks site. In it they talked about the synchronized keyword and how a synchronized block of code is locked by the actual object, not the block of code itself.

For instance, in the code below the authors state that even though the static class ‘Thingie’s setLastAccess method is listed as synchronized, the two threads defined below it can each call setLastAccess simultaneously, because they’re using different values for thingie. But if thingie is static won’t that mean they’re using the same value?

Is it the case that the variable names only need be different, even if they're referring to the same object?

public class SyncExample {
    public static class Thingie {
        private Date lastAccess;
        public synchronized void setLastAccess(Date date) {
            this.lastAccess = date;
        }
    }
    public static class MyThread extends Thread {
        private Thingie thingie;
        public MyThread(Thingie thingie) {
            this.thingie = thingie;
        }
        public void run() {
            thingie.setLastAccess(new Date());
        }
    }
    public static void main() {
        Thingie thingie1 = new Thingie(),
        thingie2 = new Thingie();
        new MyThread(thingie1).start();
        new MyThread(thingie2).start();
    }
} 
larryq
  • 15,713
  • 38
  • 121
  • 190
  • 1
    I am sure that it doesn't depend on the names of variables. Synchronized are calls on actual objects, not variables. – Al Kepp Oct 18 '11 at 18:08
  • Related to http://stackoverflow.com/questions/578904/how-do-synchronized-static-methods-work-in-java – Gray Oct 18 '11 at 18:20

4 Answers4

6

You are confusing a static method with a static class. If setLastAccess was a static method then if it is marked as synchronized, it would lock on the Class instance in the ClassLoader -- there is only one of these per loader. If the method was static and synchronized then threads would be locking on the same object.

However, in your example the Thingie class is marked as static, not the method. The static keyword on a class means that Thingie is not tied to the outer SyncExample class -- it does not mean that there is only one instance of Thingie and it does not affect synchronization. So in your example, when setLastAccess is marked synchronized, it is locking on the instance of the class Thingie (this). Since there are two instances (thingie1 and thingie2) then the locks are on different objects. Obviously, if both threads were passed in thingie1 then they would both be locking on the same object.

Here's some reading:

Gray
  • 115,027
  • 24
  • 293
  • 354
  • I appreciate the explanation. However, given that Thingie is a static class, can there be two instances (thingie1 and thingie2)? And if not, wouldn't that mean the two (synchronized) calls to setLastAccess() are being called from the same instance of Thingie? – larryq Oct 18 '11 at 20:49
  • Not sure you read my answer @larryq. The `static` keyword does _not_ mean a single instance. Read the 2nd paragraph from my answer and the "Nested Classes" link above. – Gray Oct 18 '11 at 22:19
  • Gray-- thanks much for the clarification and the links. My misunderstanding earlier about what a nested static class represents. I thought that meant it was a static member (though a class) of the outer class, and therefore couldn't be instantiated directly-- or at least, doing so would only return the one instance tied to the outer class. I was incorrect. – larryq Oct 18 '11 at 23:28
  • My apologies Gray, you're taken care of now. – larryq Nov 30 '11 at 01:02
4

This code:

class SomeClass {
    public synchronized void setLastAccess(Date date) {
    }
}

is the same as:

class SomeClass {
    public void setLastAccess(Date date) {
        synchronized(this) {
        }
    }
}

And this code:

class SomeClass {
    public static synchronized void setLastAccess(Date date) {
    }
}

is the same as:

class SomeClass {
    public static void setLastAccess(Date date) {
        synchronized(SomeClass.class) {
        }
    }
}
svaor
  • 2,205
  • 2
  • 19
  • 41
0

Nice example to explain about the static synchronized in classes in java.

I have created a method called "BookSeat" and I made it synchronized. Even I am using synchronized keyword but still I got inconsistent result. To avoid this, just put static keyword with this method and you will get correct result.

        package io.reactivestax.codepractice.mutithreading;
        class BookTheaterApp{
              static int total_seats=20;
                static synchronized void BookSeat(int ticket){
                if(total_seats>=ticket){
                    System.out.println(ticket+" Ticket booked successfully.");
                    total_seats=total_seats-ticket;
                    System.out.println("Seats left :"+total_seats);
                }else {
                    System.out.println("We cannot booked tickets ");
                    System.out.println("Required tickets: "+ticket);
                    System.out.println("Total tickets: "+total_seats);
                }
            }
        }

        class MyThread1 extends Thread{
            BookTheaterApp b1;
            int seats;
            MyThread1(BookTheaterApp b1,int seats){
                this.b1=b1;
                this.seats =seats;
            }
            @Override
            public void run(){
                b1.BookSeat(seats);
            }
        }

        class MyThread2 extends Thread{
            BookTheaterApp b2;
            int seats;
            MyThread2(BookTheaterApp b2,int seats){
                this.b2=b2;
                this.seats =seats;
            }
            @Override
            public void run(){
                b2.BookSeat(seats);
            }
        }

        public class StaticSynchro {
            public static void main(String[] args) {
                BookTheaterApp b1= new BookTheaterApp();
                MyThread1 t1= new MyThread1(b1,7);
                t1.start();
                MyThread2 t2= new MyThread2(b1,6);
                t2.start();
                BookTheaterApp b2= new BookTheaterApp();
                MyThread1 t3= new MyThread1(b2,5);
                t3.start();
                MyThread2 t4= new MyThread2(b2,7);
                t4.start();
            }
        }
Maninder
  • 1,539
  • 1
  • 10
  • 12
0

If a synchronized method is a instance method, the locking is done on each object. so if you have 2 objects obj1 and obj2 , they can execute the methods with the with their own instances locked.

If a static method is synchronized, the lock is done on the class object. So that method as well as any other static methods can't be executed when the first static synchronized method is getting executed.

java_mouse
  • 2,069
  • 4
  • 21
  • 30