public class objectcounter { private static long numofinstances = 0; public objectcounter(){ synchronized(this){ numofinstances++; } } **public static synchronized long getcount(){ return numofinstances; }** //vs// **public static long getcount(){ return numofinstances; }** } if i'll run few threads, of them call static function getcount() , of them create new instances. want in each call getcount() real number of instances @ time.
- is there difference between 2 options in code?
- if lock "
this" shouldn't mean can't callgetcount()until constructor exits synchronized block (lets if don't write synchronize on getcount()). - if synchronized block in place in code, lock synchronized block or "
this" code? - from here down edit: thank all, helpful, have few more questions following answers.
- if understand correctly, synchronized(this) block doesn't effect (or connected to) static synchronized function (in lock terms not numofinstances increment)?
- is there better option make increment , getcount() function thread-safe? (like open static object , synchronized(obj) instead synchronized(this) - friend suggested).
- if had f1() method (non-static) in objectcounter class, while 1 thread in synchronized(this) can other thread enter f1() block (not synchronized class or have synchronized block inside)?
- if had f1() method (non-static) , f2() method (non-static) in objectcounter, in f1() have synchronized(this) block. while 1 thread in synchronized(this) block, can other thread enter f1() block (not synchronized class or have synchronized block inside)? (lets both of threads "working" on same instance)
`
using synchronized means in order thread execute block or method, has acquire lock referenced (explicitly or implicitly) block or method. static synchronized methods, lock monitor on class object. synchronized(this) block, lock used monitor on current instance. sharing of locks between multiple methods or blocks enforces atomicity , memory visibility of updates, shared lock provides shared communication path through waiting , notification can take place.
since static synchronized blocks use different lock used block in constructor, entering static synchronized block not blocked thread's accessing block requires acquiring lock on current instance, , synchronized block in constructor has no effect on anything, lock acquisition uncontended. more importantly here, changes made 1 thread in constructor may not seen other threads using getter. synchronization affects both locking , memory visibility.
this changed version work:
public class objectcounter { private static long numofinstances = 0; public objectcounter(){ synchronized(objectcounter.class){ numofinstances++; } } public static synchronized long getcount(){ return numofinstances; } } because getter , incrementing block using same lock. making different threads acquire same monitor ensures change counter gets safely published thread accessing getter can see updated value.
the synchronized keyword says, "you have acquire lock before can enter", method lock assumed: static keyword on method it's monitor on class, without static keyword it's monitor on current instance. locking work correctly different blocks , methods need use same lock. there arguably syntax sugar , making things convenient in how java designed: allowing implicit choice of locks , putting monitor on java.lang.object can cause confusion.
wrt question #6: you're doing here you'd better off atomiclong. use synchronized blocks coordinating multiple changes need take place without interference other threads.
questions #3, #7 , #8 seem similar: if method/block isn't attempting acquire lock, nothing prevents threads executing method/block. object whole doesn't protection, using synchronized methods or blocks enforce locking protecting. think less in terms of "using synchronized keyword" , more in terms of lock threads need acquire.
Comments
Post a Comment