Results 1 to 11 of 11
  1. #1
    kiza is offline Member
    Join Date
    Dec 2008
    Posts
    3
    Rep Power
    0

    Question Synchronized(this)?

    Hi everybody :) I am here for the first time and this is my first post. I am young student from Serbia. Well, i will go to the point. My question is: what synchronized(this) do in this code?

    private boolean radi=false;

    public void run() {
    try {
    while(!interrupted()) {
    if(!radi) synchronized(this)
    { while(!radi) wait(); }
    ....
    }
    } catch(InterruptedException g) {}
    }

    public void pocni() { start(); }
    public void stani() { radi = false; }
    public synchronized void kreni() { radi = true; notify(); }
    public void zavrsi() { interrupt(); }

    I understand that synchronized block and synchronized methods provide while they carry out nothing else (synchronized) can not be call, but again this confuses me.... More interested in me and why the method "stani" is not synchronized because it the changes the state of shared data "radi". (in collection from which i styde this modifier not exist and so i understand that should not be). I also ask does this code is really good?.... Every advice appreciate!
    Last edited by kiza; 12-28-2008 at 07:08 PM. Reason: work - do

  2. #2
    neilcoffey is offline Senior Member
    Join Date
    Nov 2008
    Posts
    286
    Rep Power
    7

    Default

    The code as it stands is indeed a bit broken. You need to be consistent about how the "radi" variable is synchronized between threads. If the way it is synchronized is by synchronizing on "this", then you essentially need to synchronize on every access (reading or writing). So the stani() method should be synchronized, and the read outside of the synchronized block inside run() should be removed.

  3. #3
    kiza is offline Member
    Join Date
    Dec 2008
    Posts
    3
    Rep Power
    0

    Default

    Thanks! Yes, you were right. I made a mistake on typing, while(!radi) not exist in method "run"... But i still don't understand why is necessary synchronized(this) or what it actually do

  4. #4
    neilcoffey is offline Senior Member
    Join Date
    Nov 2008
    Posts
    286
    Rep Power
    7

    Default Synchronizes on the "current" object

    In general, "synchronized" is used to safely access variables/data by more than one thread. In general, whenever you read or write any variable that is accessed by more than one thread, you need to make sure that those accesses don't conflict with one another. A common way to do so is via a synchronized block. The idea is that you write code inside a synchronized block that synchronizes on a particular object:
    Java Code:
    synchronized (obj) {
      // access some variables in a thread-safe manner
    }
    Now, any code that does the above, synchronizing on the same object will be able to access shared data safely inside the synchronized block, because only one thread at a time is allowed to execute code synchronized on the object in question. (Strictly, entering a synchronized block involves acquiring a "lock" on that object, and exiting involves releasing that lock.) There are also some more complex issues that synchronization resolves, such as data visibility between threads (if thread A or indeed the processor doesn't know that some other thread B might access a given variable, it might not write it to main memory at the time you expect relative to other operations-- or even at all).

    Synchronizing on "this" just means synchronizing on "the current object" whose method is being executed. Declaring a method synchronized, as in your kreni() method, is essentially the same as putting the entire method inside a "synchronized (this)" block. (In the case of a static method, it would synchronize on corresponding the class object.)

    Now, it also turns out that to use wait() and notify(), the thread calling either of those methods also has to be synchronized on the object it wants to call the methods on at the time of doing so.

    Some articles I've written around this subject:
    Last edited by neilcoffey; 01-02-2009 at 08:22 AM.

  5. #5
    kiza is offline Member
    Join Date
    Dec 2008
    Posts
    3
    Rep Power
    0

    Default

    Thank you very much for this explanation!

  6. #6
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    8

    Default

    Just a brief suggestion. Rather than synchronizing on "this", I create an Object and use that:
    Java Code:
    private final Object _SyncObject = new Object();
    .
    .
    .
    public void run() {
    ...
      synchronized(_SyncLock) {
        ...
      }
    ...
    }
    Multiple threaded programs have several problems. One is that two threads that access the same field at the same time can lead to invalid values in the field. Another is "local copies" of instance variables. That means each thread can, if the runtime decides to, make its own copies of the instance's fields and change them. This happens arbitrarily. "synchronized", forces threads to take turns accessing fields, and it forces all the local copies to be updated. Therefore, it is very important to synchronize your code.

    At the same time, there are different ways to synchronize. I suggest using only the one above, since it is easy, flexible, explicit, and it makes your code consistent.

    When your applications get bigger, you can have an object that has several methods that need to synchronize for *different reasons*. By creating a separate object for each reason, you ensure that threads don't end up waiting for each other for no reason, which can make your application slow. In the worst case, it could hang.

    Synchronized methods use "this" as their lock object, which can lead to the conflicts I mentioned above. Also, synchronized methods cause all the code in the method to execute under the lock, which means the lock is held longer than is needed. Last, mixing synchronized methods with synchronized blocks means you have two approaches, which is less clear.

    I am writing an application with hundreds of threads, so I am sensitive to the issue.

  7. #7
    neilcoffey is offline Senior Member
    Join Date
    Nov 2008
    Posts
    286
    Rep Power
    7

    Default

    Agreed, there are problems with a class's locking mechanism being either "this" or indeed any object that it exposes. Usually I'd advise synchronizing on "this" when that is what the user of the object would logically expect to lock on: e.g. it makes sense for things like collections. But yes, if the internal locking isn't something you need to expose to the caller, then I'd recommend synchronizing on a private object not exposed to the caller.

  8. #8
    Nicholas Jordan's Avatar
    Nicholas Jordan is offline Senior Member
    Join Date
    Jun 2008
    Location
    Southwest
    Posts
    1,018
    Rep Power
    8

    Post why the method "stani" is not synchronized

    These other two posters know what they are doing and it looks like the have plenty of help for you so I am going to take the:
    More interested in me and why the method "stani" is not synchronized because it the changes the state of shared data "radi"
    as you state all answers wanted.

    In compiling, there has to be a way to track where everything is. Let us take some arbitrary code:
    Java Code:
    class arbitrary_code{arbitrary_code(){return;}}
    the somewhere at another location in the code we do:
    Java Code:
    arbitrary_code ac = new arbitrary_code();
    so where do we put this, more correctly, let us generate code that will track where they are if several, even hundreds are created. The first thing the compiler does is take a hashcode of something. Probably the class name, for this simple discussion, we do not even need that. A hashcode is just " a number, some number, it does not matter as long as the number is unique for any given input,..."

    Then the compiler has a way to reference the object when code calls a "new" on that type of object. It just works better to start with a number, gets sorta involved but is simple in principle. Then with a hashcode and a call to new at runtime, things can be heaped up in an allocated memory. Program gets brought in from persistent memory that will stay fixed across power-down and reboot. At that point, the address of main() is available to the operating system because we design the whole machine to work that way. Be that as it may, at some point an address is loaded into an area of main processor board intended for running programs and ,.... whambi-dambi, there goes bambi.

    Now, after multiple threads are running, one of those whambi-dambis gets public void run() { as the place to go next. That may be stani in your code, it could be Arbitration Act, 9 U.S.C. 1 et seq. .... it could be the repo-man in the driveway,... does not matter - it is some activity wants to boogie with stani..,,,,.... if you put the synchronized at stani, there is the possibility of several people holding synchronized tickets. If you put the synchronized at where the code has it, the word "this" in the code is what the compiler used to track the hashcode of public void run() or the variables or whatever. Now I see why nielcoffey said your code somewhat broken, it does not have all the details to work the question properly .....

    Java Code:
    public void pocni() { start(); }
    public void stani() { radi = false; }
    public void zavrsi() { interrupt(); }
    well those should all go through
    Java Code:
    public synchronized void kreni() { radi = true; notify(); }
    in fact all access ....

    Anyway, once you implement whatever the other posters suggest, which is probably implementation of get and set methods .... you still have to have one and only one portal, to do otherwise results in what is called the "Double Checked Singelton Locking is Broken" paradigm. Studied well in every study guide for Certification, it can be proven mathematically that without dedicated hardware and tweaked instructions for that hardware, there is no way to determine exactly when the contention for "this" will occur if there are two or greater ways for operational execution to arrive at obtaining both a "lock" on two or greater locks.

    There is a lot of wasted effort in computer science due to "computer science for art students" generating copious verbosity to keep everyone in the soft, warm glow of fuzzy logic. Great when the parents have the abiltity to waste a thousand dollars a day on someone who will never work a day in their life. A real pain for someone who actually wants to operate computing machinery.

    By placing synchronized this at the entry, all of the tickets have to go through that code one at a time, your observation is correct. Any access to radi must go through one and only one codepoint,....

    There are some other finess, such as an int will read access atomically so maybe read()'s may be done blindside without synchronization + the common sloution is to have an Object, just plain nothing to it Object, and have sync happen on that object, as well there is wait() and interrupt() but due to the nature of real life, there is no way to do that even semi-portably that will cross operational domains of commercial boundaires and do so effectively and reliably.

    Beware the Code Puppies..... ( interns )
    Introduction to Programming Using Java.
    Cybercartography: A new theoretical construct proposed by D.R. Fraser Taylor

  9. #9
    neilcoffey is offline Senior Member
    Join Date
    Nov 2008
    Posts
    286
    Rep Power
    7

    Default

    Hmmm... if you'd asked me the question "why the method "stani" is not synchronized" I'd have said "it's a bug".

  10. #10
    Nicholas Jordan's Avatar
    Nicholas Jordan is offline Senior Member
    Join Date
    Jun 2008
    Location
    Southwest
    Posts
    1,018
    Rep Power
    8

    Default

    he did ask that, it appears to me the 'bug' is placing sync directly in the run method.
    Java Code:
    public void pocni() { start(); }
    public void stani() { radi = false; }
    public synchronized void kreni() { radi = true; notify(); }
    public void zavrsi() { interrupt(); }
    so poster put some kind of code up to direct attention to sync issues and related, true, but the code is not effective at presenting clear design pardigms. ( para-digums? ) start() is in the wrong place, is as interrupt() + the while is on interrupted() but that method is not shown,....

    looks like not exactly a bug, more along the lines of code and blunder, stare and wonder.....
    Introduction to Programming Using Java.
    Cybercartography: A new theoretical construct proposed by D.R. Fraser Taylor

  11. #11
    Join Date
    Apr 2009
    Posts
    5
    Rep Power
    0

    Default

    public void pocni() { start(); }
    public void stani() { radi = false; }
    public synchronized void kreni() { radi = true; notify(); }
    public void zavrsi() { interrupt(); }

Similar Threads

  1. Synchronized Servlet
    By udayadas in forum Java Servlet
    Replies: 5
    Last Post: 09-09-2008, 09:14 PM
  2. synchronized
    By bugger in forum New To Java
    Replies: 2
    Last Post: 11-28-2007, 11:33 AM
  3. doubt about synchronized
    By simon in forum Advanced Java
    Replies: 2
    Last Post: 08-05-2007, 04:49 AM
  4. Return in the Middle of synchronized Block
    By ariak in forum Advanced Java
    Replies: 1
    Last Post: 07-26-2007, 11:24 AM

Posting Permissions

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