java - Why can't a thread-unsafe class work while using just getter and setter? -
i have class follow:
public class boolflag { boolean flag; public boolflag() { flag=false; } public synchronized void setflag(boolean flag) { this.flag=flag; } public synchronized boolean getflag() { return flag; } }
if don't set getter , setter synchronized,it cause problem follow:
when set object of boolflag called imageready in 1 buttonclick listiner:
if (status == jfilechooser.approve_option) { try { system.out.println("file chosen"); imgfile=chooser.getselectedfile(); image.setimg( imageio.read(imgfile) ); imageready.setflag(true); } catch(exception e) { system.out.println("file not opened"); } }
then in thread:
public void run() { boolean running=true; while(running) { // system.out.println("img sender running"); if(imageready.getflag()) { system.out.println("trying send img"); try { outputstream outputstream = img_s.getoutputstream(); imageio.write(image.getimg(), "jpg", outputstream); system.out.println("send image"+system.currenttimemillis()); outputstream.flush(); outputstream.close(); imageready.setflag(false); } catch(exception e) { system.out.println("image client send failed"); imageready.setflag(false); } } } }
what expect after choosing file, imageready should set true, thread flag execute statements inside block:
if(imageready.getflag()){...send image...}
but won't goes block though imageready set true.
as might notice, have statement being commented out right before if block:
// system.out.println("img sender running");
if don't comment out, statements in if block executed. putting other unrelated statements sleep(100) result in same effect. if put break point @ if(imageready.getflag()), , execute step step,it goes block.
if set getter , setter synchronized, these problem won't happen. seems it's tread-safe class can't figure out why matter though use getter , setter.
your accessor being inlined such field read, , runtime may optimize away simple field reads appear in loop such value read once.
you can avoid reading volatile
value or, noticed, using synchronized
force memory barrier when flag written , read.
in case, use atomicboolean
in place of boolflag
class.
on side note, avoid busy-spinning on "image ready" flag on second thread. consider using wait notification mechanism, e.g., countdownlatch
count of 1
.
Comments
Post a Comment