Page 1 of 2 12 LastLast
Results 1 to 20 of 21
  1. #1
    newbiejava is offline Senior Member
    Join Date
    Jan 2010
    Posts
    138
    Rep Power
    0

    Default Synchronization on non-final field

    I am facing with Synchronization on non-final field .. warning message
    Java Code:
    protected  Map returnListeners;
    
    public  void addReturnListener(long invokeId, MyReturnListener listener) {
                	synchronized (returnListeners) { //Synchronization on non-final field
    			returnListeners.put(new Long(invokeId), listener);
    		}
            }
    what does it mean? what should I check?

  2. #2
    Zack's Avatar
    Zack is offline Senior Member
    Join Date
    Jun 2010
    Location
    Destiny Islands
    Posts
    692
    Rep Power
    5

    Default

    When you're trying to synchronize multiple threads, they have to be synchronized based on the same object reference/instance. This ensures that they both synchronize at the same time based on the same data.

    Hope that makes a bit of sense; you just have to synchronize based on a finalized variable rather than a dynamic one.

  3. #3
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,386
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by newbiejava View Post
    I am facing with Synchronization on non-final field .. warning message

    what does it mean? what should I check?
    You synchronize on objects, not on references thereof; suppose one thread synchronizes on an object (using a reference); another thread changes the reference to another object so no other thread can synchronize on the original object anymore (assuming that you don't have other references to the object available). Your code doesn't produce an error but it can go horribly wrong if you don't pay attention, hence the warning message.

    kind regards,

    Jos

  4. #4
    Zack's Avatar
    Zack is offline Senior Member
    Join Date
    Jun 2010
    Location
    Destiny Islands
    Posts
    692
    Rep Power
    5

    Default

    Actually it's more than a warning message; unless one uses a final variable, the code will not compile. (It's a compile-time error rather than a run-time error, if that's what you're getting at.)

  5. #5
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,386
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by Zack View Post
    Actually it's more than a warning message; unless one uses a final variable, the code will not compile. (It's a compile-time error rather than a run-time error, if that's what you're getting at.)
    Can you show me/us a code snippet where this situation actually causes a compile time error (instead of just a warning)? The following snippet doesn't even make the compiler whine:

    Java Code:
    public class T {
    	// not a final field ...
    	public Object lock= new Object();
    	
    	public T() {
    		synchronized (lock) {
    			System.out.println(lock);
    		}
    	}
    	
    	public void m() {
    		synchronized (lock) {
    			System.out.println(lock);			
    		}
    	}
    }
    kind regards,

    Jos

  6. #6
    Zack's Avatar
    Zack is offline Senior Member
    Join Date
    Jun 2010
    Location
    Destiny Islands
    Posts
    692
    Rep Power
    5

    Default

    Ah, weird. I think my mistake was in accidentally checking against an integer field rather than with an object. It produces the same error:
    Java Code:
    public class X {
        public static int q = 5;
        public final static Object r = 6;
        public X() {
            synchronized (q) { // Error
                X.q++;
            }
            synchronized (r) { // No error
                X.q++;
            }
        }
    }
    Thanks for clearing that up. ;)

  7. #7
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,386
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by Zack View Post
    Ah, weird. I think my mistake was in accidentally checking against an integer field rather than with an object. It produces the same error:
    Thanks for clearing that up. ;)
    Tell you what: I didn't even know you could sync on a primitive because it even isn't an object. Thanks for clearing that up for me ;-)

    kind regards,

    Jos

  8. #8
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,386
    Blog Entries
    7
    Rep Power
    20

    Default

    A bit more info for the above: you can't sync on a primitive, whether it's final or not so my first reply is still valid.

    kind regards,

    Jos

  9. #9
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,306
    Rep Power
    25

    Default

    Did the OP ever say if he/she got the code to work?

    My experience with final requirements was for anonymous inner classes referencing a parm in a method. The compiler wanted the variable nailed down so it would be there when the code was called and the outer method(and its parms) had gone away.

  10. #10
    newbiejava is offline Senior Member
    Join Date
    Jan 2010
    Posts
    138
    Rep Power
    0

    Default

    protected Map returnListeners;

    public void addReturnListener(long invokeId, MyReturnListener listener) {

    synchronized (returnListeners) // ==> THE WARNING GOES HERE!

    {
    returnListeners.put(new Long(invokeId), listener);
    }

    }

    please help

    thanks

  11. #11
    Zack's Avatar
    Zack is offline Senior Member
    Join Date
    Jun 2010
    Location
    Destiny Islands
    Posts
    692
    Rep Power
    5

    Default

    ...did you even read any of the posts above?

    Quote Originally Posted by Zack
    When you're trying to synchronize multiple threads, they have to be synchronized based on the same object reference/instance. This ensures that they both synchronize at the same time based on the same data.

    Hope that makes a bit of sense; you just have to synchronize based on a finalized variable rather than a dynamic one.
    Quote Originally Posted by JosAH
    You synchronize on objects, not on references thereof; suppose one thread synchronizes on an object (using a reference); another thread changes the reference to another object so no other thread can synchronize on the original object anymore (assuming that you don't have other references to the object available). Your code doesn't produce an error but it can go horribly wrong if you don't pay attention, hence the warning message.

  12. #12
    newbiejava is offline Senior Member
    Join Date
    Jan 2010
    Posts
    138
    Rep Power
    0

    Default

    Thanks Zack, you awaring me, but sorry, I still not not understand why this can be happened?

    does it related because of the "import java.util.Hashtable;" is obsolete?

    Java Code:
    import java.util.Hashtable;
    import java.util.HashSet;
    
    public class MyLink {
     protected Map returnListeners;
     protected Set eventListeners;
    
     public MyLink() {
      returnListeners = new Hashtable();
      eventListeners = new HashSet();
     }
    
    public void addReturnListener(long invokeId, MyReturnListener 
    listener) {
      synchronized (returnListeners) { // --> THE WARNING GOES HERE!
       returnListeners.put(new Long(invokeId), listener);
      }
     } 
    
    ..
    ...

  13. #13
    Zack's Avatar
    Zack is offline Senior Member
    Join Date
    Jun 2010
    Location
    Destiny Islands
    Posts
    692
    Rep Power
    5

    Default

    Are you just not familiar with final variables?
    final : Java Glossary

    ...or do you just not understand why the variable has to be final?

  14. #14
    newbiejava is offline Senior Member
    Join Date
    Jan 2010
    Posts
    138
    Rep Power
    0

    Default

    thanks Zack!.. its cleared now! :)

  15. #15
    Cbani is offline Member
    Join Date
    Jan 2010
    Posts
    90
    Rep Power
    0

    Default

    Guys, I have a question here on thread synchronization.

    What is the use of making a static method synchronized; threads get synchronized on a particular object and every object has only one lock. Having said that, i do not have to synchronize a static method (class level). But I found from some sources that if a static method is marked as synchronized then the class level lock is taken.

    I am not able to understand this class level lock concept; wherein threads synchronize on objects (object level lock).

    Please clarify.

  16. #16
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,386
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by Cbani View Post
    Guys, I have a question here on thread synchronization.

    What is the use of making a static method synchronized; threads get synchronized on a particular object and every object has only one lock. Having said that, i do not have to synchronize a static method (class level). But I found from some sources that if a static method is marked as synchronized then the class level lock is taken.

    I am not able to understand this class level lock concept; wherein threads synchronize on objects (object level lock).

    Please clarify.
    A class itself also is an object of type Class; read the API documentation for that class and the getClass() method and the '.class' notation.

    kind regards,

    Jos

  17. #17
    Cbani is offline Member
    Join Date
    Jan 2010
    Posts
    90
    Rep Power
    0

    Default

    A class itself also is an object of type Class; read the API documentation for that class and the getClass() method and the '.class' notation.

    kind regards,
    Thanks Josah.

    Still I am having a doubt that if the method is a static one (class level); what difference would that make if i mark it synchronized.

    In this below example if i remove synchronized; still i would get the same output.
    Java Code:
    public class SynchronizedMethod extends Object {
    	private static int count = 1;
    
    	public static  [B]synchronized [/B]int getCount() {
    		int i = count;
    		count++;
    		return i;
    	}
    
    	private static void print(String msg) {
    		String threadName = Thread.currentThread().getName();
    		System.out.println(threadName + ": " + msg);
    	}
    
    	public static void main(String[] args) {
    		try {
    			Runnable runnable = new Runnable() {
    				public void run() {
    					System.out.println("count=" + getCount());
    				}
    			};
    			Thread threadA = new Thread(runnable, "ThreadA");
    			threadA.start();
    			Thread.sleep(500);
    			Thread threadB = new Thread(runnable, "ThreadB");
    			threadB.start();
    			Thread.sleep(500);
    			Thread threadC = new Thread(runnable, "ThreadC");
    			threadC.start();
    			Thread.sleep(500);
    			Thread threadD = new Thread(runnable, "ThreadD");
    			threadD.start();
    		} catch (Exception x) {
    		}
    	}
    }
    Please help in clarifying my confusions.

  18. #18
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,386
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by Cbani View Post
    Thanks Josah.

    Still I am having a doubt that if the method is a static one (class level); what difference would that make if i mark it synchronized.

    In this below example if i remove synchronized; still i would get the same output.
    Those (small) threads don't take 0.5 seconds to run so there isn't a clash on your shared resource 'count'.

    kind regards,

    Jos

  19. #19
    Cbani is offline Member
    Join Date
    Jan 2010
    Posts
    90
    Rep Power
    0

    Default

    Hi Josah,

    I tried to replicate the same by the below code; but still looks to be the same

    Java Code:
    package test;
    
    public class SynchronizedMethod extends Object {
    	private static int count = 1;
    
    	public static  int getCount() {
    		int i = count;
    		count++;
    		System.out.println(Thread.currentThread().getName());
    		try {
    			Thread.currentThread().sleep(5000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		return i;
    	}
    
    	public static void main(String[] args) {
    		try {
    			Runnable runnable = new Runnable() {
    				public void run() {
    					System.out.println("count=" + getCount());
    				}
    			};
    			Thread threadA = new Thread(runnable, "ThreadA");
    			threadA.start();
    			Thread.sleep(500);
    			Thread threadB = new Thread(runnable, "ThreadB");
    			threadB.start();
    			Thread.sleep(500);
    			Thread threadC = new Thread(runnable, "ThreadC");
    			threadC.start();
    			Thread.sleep(500);
    			Thread threadD = new Thread(runnable, "ThreadD");
    			threadD.start();
    		} catch (Exception x) {
    		}
    	}
    }
    would you please paste here a proper example of using synchronized in a static method(wherein if i remove synchronized keyword from the class i would get different op)

  20. #20
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,386
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by Cbani View Post
    Hi Josah,

    I tried to replicate the same by the below code; but still looks to be the same
    My comments still apply (see my previous reply): you fire up a thread each 0.5 seconds; it increments a variable and sleeps for 5 seconds itself. Still no deadly embrace or anything. Make your threads run a loop:

    Java Code:
    while(true) {
       int i= code+1; // guess the next value
       if (i != ++code) // did something else touch the resource
         System.out.println("resource changed behind my back")
    }
    kind regards,

    Jos

Page 1 of 2 12 LastLast

Similar Threads

  1. Replies: 4
    Last Post: 01-17-2010, 11:13 PM
  2. [SOLVED] is final class members are also final ?
    By haoberoi in forum New To Java
    Replies: 4
    Last Post: 11-10-2008, 03:01 PM
  3. static final field
    By techie.it19 in forum New To Java
    Replies: 3
    Last Post: 10-16-2008, 04:12 AM
  4. FInal field cannot be assigned
    By ravian in forum New To Java
    Replies: 3
    Last Post: 12-13-2007, 02:26 PM
  5. Final field question
    By derrickD in forum Advanced Java
    Replies: 1
    Last Post: 04-28-2007, 10:37 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •