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

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -