JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$...

20
Java Programming Unit 11 Threads. Advanced topics. (c) Farata Systems, L.L.C. 2011

Transcript of JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$...

Page 1: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

Java  Programming    Unit  11  

Threads.  Advanced  topics.    

(c)  Farata  Systems,  L.L.C.    2011  

Page 2: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

Thread  Synchroniza/on  and  Race  Condi/ons    

•  A  race  condi*on  may  happen  when  mulEple  threads  need  to  modify  the  same  program  resource  at  the  same  Eme  (concurrently).      

•  A  classic  example:  a  husband  and  wife  are  trying  to  withdraw  cash  from  different  ATMs  at  the  same  Eme.    

•  To  prevent  race  condiEons  Java  always  offered  the  keyword  synchronized.  The  preferred  way  though  is  the  class    java.uEl.concurrent.locks.ReentrantLock.    

•  The  synchronized  places  a  lock  (a  monitor)  on  an  important  object  or  piece  of  code  to  make  sure  that  only  one  thread  at  a  Eme  will  have  access  to  it.      

(c)  Farata  Systems,  L.L.C.    2011  

Page 3: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

Minimize  the  locking  periods  

(c)  Farata  Systems,  L.L.C.    2011  

class  ATMProcessor  extends  Thread{        …      synchronized  withdrawCash(int  accountID,  int  amount){          //  Some  thread-­‐safe  code  goes  here,  i.e.  reading  from            //  a  file  or  a  database              …        boolean  allowTransacEon  =  validateWithdrawal(accountID,                                                                                                          amount);        if  (allowTransacEon){                updateBalance(accountID,  amount,  “Withraw”);        }        else  {                System.out.println(“Not  enough  money  on  the  account”);          }      }    }    

class  ATMProcessor  extends  Thread{      …    withdrawCash(int  accountID,  int  amount){          //  Some  thread-­‐safe  code  goes  here,  i.e.  reading  from            //  a  file  or  a  database        …      synchronized(this)  {        if  (allowTransacEon){          updateBalance(accountID,  amount,  “Withdraw”);        }        else  {          System.out.println(                                                                “Not    enough  money  on  the  account”);          }      }    }  }  

Synchronizing  the  enEre  method  

Synchronizing  the  code  block  

Page 4: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

How  to  Kill  a  Thread  

•  The  method  Thread.stop()  is  deprecated.  Don’t  use  it  as  it  may  leave  your  program  resources  locked.    

•  You  can  declare  some  flag  variable,  say  stopMe,  in  your  thread  and  test  it  periodically  in  a  loop  condiEon  –  exit  the  loop  if  this  flag  is  set.    

•  You  can  call  the  method  interrupt()  on  the  Thread  to  stop  it.    

(c)  Farata  Systems,  L.L.C.    2011  

Page 5: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

Killing  a  thread  by  seeng  a  flag  

(c)  Farata  Systems,  L.L.C.    2011  

class  KillTheThread{                          public  staEc  void  main(String  args[]){                    Porholio4  p  =  new  Porholio4("Porholio  data");                      p.start();                                        //  Some  other  code  goes  here                  //      …                      //  and  now  it's  Eme  to  kill  the  thread                      p.stopMe();                    //  This  method  won’t  work  if  a  thread  is  not                  //    doing  any  processing,  e.g.  waits  for  the  user’s                //    input.  In  such  cases  use  p.interrupt();        }  }  

class  Porholio4  extends  Thread{    private  vola/le  boolean  stopMe  =  false;                        public  void  stopMe()  {                  stopMe  =  true;          }            public  void  run()  {                  while  (!stopMe)  {                      try{                          //Do  some  porholio  processing  here                      }catch(InterruptedExcepEon  e  ){                          System.out.println(Thread.currentThread().getName()                                                                                    +  e.toString());                  }              }    }  

The  variable  stopMe  has  been  declared  with  a  vola/le  keyword,  which  warns  the  Java  compiler  that  another  thread    can  modify  it  and  that  this  variable  shouldn’t  be  cached  in  registers,  so  that  all  threads  must  always  see  its  fresh  value.    

Page 6: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

Wait  and  NoEfy  

(c)  Farata  Systems,  L.L.C.    2011  

The  class  Object  also  has  some  methods  relevant  to  threads:    wait(),  noEfy(),  and  noEfyAll().      wait(1000)  means  that  the  current  thread  has  to  wait  for  some  noEficaEon  from  another                                            thread    for  up  to  1  second  (a  thousand  milliseconds)    A  thread  can  noEfy  other  thread(s)  by  calling  methods  noEfy()  or  noEfyAll().  

sleep(1000)  yield  the  control  to  the  CPU  for  exactly  one  second.  

 synchronized  (this)  {        try{            wait(1000);              }  catch  (InterruptedExcepEon  e){    …}    }    

Page 7: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

Wait-­‐NoEfy  Code  Sample  

(c)  Farata  Systems,  L.L.C.    2011  

class  ClassA    {    String  marketNews  =  null;      void    someMethod(){          //  The  ClassB  needs  a  reference  to  the  locked  object          //  to  be  able  to  noEfy  it                ClassB  myB=new  ClassB(this);            myB.start();            synchronized(this)  {          wait();        }          //  Some  further  processing  of  the  MarketData          //  goes  here      }            public  void  setData  (String  news){          marketNews  =  news;      }  }  

class  ClassB  extends  Thread{          ClassA  parent  =  null;          ClassB(ClassA  caller){            parent  =  caller;  //  store  the  reference  to  the  caller          }          run(){          //  Get  some  data,  and,  when  done,  noEfy  the  parent          parent.setData(“Economy  is  recovering…”);          …                    synchronized  (parent){            parent.no/fy();    //noEficaEon  of  the  caller          }        }  }  

Page 8: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

Walkthrough  1  1.  In  Eclipse  Copy/Paste  the  class  TestThreads3  from  Lesson20  Eclipse  project  to  create  a  class  TestThreadsWait    2.  Add  the  code  below  in  the  method  main  above  the  println()  method  call:  

(c)  Farata  Systems,  L.L.C.    2011  

             Object  theLockKeeper  =  new  Object();                                        synchronized  (theLockKeeper)  {                          try{                            theLockKeeper.wait(15000);                                }  catch  (InterruptedExcepEon  e){                              System.out.println("The  main  thread  is  interrupted");                          }                      }  

3.  Run  the  program  –  now  it  waits  for  15  seconds  before  prinEng  the            “finished  ”  message.    4.  What  has  to  be  done  to  make  this  program  wait  for  less  than  15  seconds?  

Page 9: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

Joining  Threads  

(c)  Farata  Systems,  L.L.C.    2011  

If  one  thread  needs  to  wait  for  the  compleEon  of  another,    you  can  use  the  method  join()  

public  class  TestThreadJoin  {            public  staEc  void  main(String  args[]){                      MarketNews3  mn  =  new  MarketNews3("Market  News");                    mn.start();                      Porholio3  p  =  new  Porholio3("Porholio  data");                    p.start();                      try{                      mn.join();                      p.join();                      }catch  (InterruptedExcepEon  e){                      e.printStackTrace();                    }                                      System.out.println(  "The  main  method  of  TestThreadJoin  is  finished");            }  }  

Page 10: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

Walkthrough  2  

1.  Import  the  code  samples  from  Lesson  21  of  the  textbook    2.  Review  the  code  of  the  program  TestThreadsJoin  and  run  it.      3.  Observe  the  output  –  the  main  thread  waits  for  the  compleEon  of  the  threads  MarketNews3  and  Porholio3    

(c)  Farata  Systems,  L.L.C.    2011  

Page 11: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

java.uEl.concurrent.locks.ReentrantLock  

(c)  Farata  Systems,  L.L.C.    2011  

The  class  ReentrantLock  is  a  beter  performing  soluEon  than  the  keyword  synchronized    Place  a  lock  before  the  secEon  of  your  program  that  may  cause  a  race  condiEon,    and  to  remove  the  lock  auerward.    

private  Lock  accountLock  =  new  ReentrantLock();      witdrawCash(int  accountID,  int  amount){          //  Some  thread-­‐safe  code  goes  here,  i.e.  reading  from            //  a  file  or  a  database        …            accountLock.lock();  //  place  a  lock  when  this  thread  enters  the  code            try{        if  (allowTransacEon){          updateBalance(accountID,  amount,  “Withdraw”);        }        else  {          System.out.println(“Not    enough  money  on  the  account”);          }      }finally  {            accountLock.unlock();  //  allow  other  threads  to  update  balance      }      }  

Page 12: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

Executor  Framework  

(c)  Farata  Systems,  L.L.C.    2011  

CreaEng  threads  by  subclassing  Thread  or  implemenEng  Runnable  has  shortcomings:    1.    The  method  run()  cannot  return  a  value.      2.  An  applicaEon  may  spawn  so  many  threads  that  it  can  take  up  all  the  system  resources.  

You  can  overcome  the  first  shortcoming  by  using  the  Callable  interface,    and  the  second  one  by  using  classes  from  the  Executor  framework.      The  Executors  class  spawns  the  threads  from  Runnable  objects.      ExecutorService  knows  how  to  create  Callable  threads.      ScheduledExecutorService  allows  you  to  schedule  threads  for  future  execuEon.    

Page 13: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

The  class  Executors  

(c)  Farata  Systems,  L.L.C.    2011  

The  class  Executors  has  staEc  methods  that  create  an  appropriate    executor.      Its  method  newFixedThreadPool()  creates  a  pool  of  threads  of  a    specified  size,  e.g.  you  can  create  a  pool  that  allows  not  more    than  5  threads:      Executors.newFixedThreadPool(5);    

Page 14: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

Callable  Interface  

(c)  Farata  Systems,  L.L.C.    2011  

If  you  need  to  return  the  data  from  a  thread  use  Callable,  which  Java  defines  as  follows:    public  interface  Callable  <V>{        V  call()  throws  ExcepEon;  }  

public  class  Porholio  implements  Callable<Integer>{          public  Integer  call()  {              //  Perform  some  acEons              return  someInteger;      }  }      public  class  MarketData  implements  Callable<Integer>{          public  Integer  call()  {              //  Perform  some  acEons              return  someInteger;        }  }  

The  class  Executors  has  a  number  of  staEc    methods  that  will  create  a  thread  from  your    Callable  class  and  return  the  result  of  its    execuEon  as  a  special  object    implemenEng  the  interface  Future.    

Page 15: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

The  Future  Object  

(c)  Farata  Systems,  L.L.C.    2011  

To  create  a  Future  object,  submit  an  instance  of  the  Callable  thread  to  the  Executor.    Call  the  funcEon  get()  on  the  Future  instance,  and  it’ll  block  on  the  thread    unEl  its  call()  method  returns  the  result:    //Threads’  results  can  be  stored  in  the  collecEon  of  Futures  List<Future<Integer>>    threadResults=  new  ArrayList<Future<Integer>>();      

//  Submit  Callables  for  execuEon  threadResults.add(myExecutorService.submit(new  Porholio()));  threadResults.add(myExecutorService.submit(new  MarketData()));      //Wait  for  threads  to  complete  for  (Future<Integer>  future  :  threadResults)  {                      future.get();    //  an  equivalent  of  joining  threads  }    

Page 16: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

How  to  Spawn  a  Callable  Thread    

(c)  Farata  Systems,  L.L.C.    2011  

1.  Declare  and  instanEate  a  class  that  implements  the  Callable  interface,                    and  program  the  business  logic  in  its  method  call().    2.  Create  an  instance  of  the  Future  object.    3.  Create  an  instance  of  an  ExecutorService  using  Executors.newFixedThreadPool().    4.  Call  the  funcEon  submit()  on  the  ExecutorService,  providing  an  instance  of                      the  Callable  object  as  an  argument.    5.  Call  the  funcEon  get()  on  the  Future  object  from  Step  2.                        This  funcEon  will  wait  unEl  the  thread  returns  the  result  (or  throws  an  excepEon).    6.  Accept  the  result  of  the  thread  execuEon  into  a  variable  of  the  data  type  used  in  Step  1.    7.  Call  the  funcEon  shutdown()  on  the  ExecutorService  from  Step  3.      

Page 17: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

Callable  Porholio  and  MarketNews  

(c)  Farata  Systems,  L.L.C.    2011  

class  PorholioCallable  implements  Callable<Integer>  {            public  Integer  call()  throws  ExcepEon  {            for  (int  i=0;  i<5;i++){  

 Thread.sleep  (700);        //  Sleep  for  700  milliseconds                    System.out.println(  "You  have  "  +    (500  +  i)  +                                                                                  "  shares  of  IBM");        }                //  Just  return  some  number  as  a  result        return  10;          }        }  

class  MarketNewsCallable  implements  Callable<Integer>  {            public  Integer  call()  throws  ExcepEon  {                      for  (int  i=0;  i<5;i++){                  Thread.sleep  (1000);    //  sleep  for  1  second                  System.out.println(  "The  market  is  improving  "  +  i);            }            //  Just  return  some  number  as  a  result        return  12345;          }        }    

Page 18: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

TesEng  Callable  Porholio  and  MarketNews  

(c)  Farata  Systems,  L.L.C.    2011  

public  class  TestCallableThreads  {                  public  staEc  void  main(String[]  args)              throws  InterruptedExcepEon,  ExecuEonExcepEon  {                      //A  placeholder  for  Future  objects  

 List<Future<Integer>>  futures  =        new  ArrayList<Future<Integer>>();                      //  A  placeholder  for  results  

 List<Integer>  results  =  new  ArrayList<Integer>();                final  ExecutorService  service  =                  Executors.newFixedThreadPool(2);  //  pool  of  2  threads                      try  {                    futures.add(service.submit(new  PorholioCallable()));              futures.add(service.submit(new  MarketNewsCallable()));                for  (Future<Integer>  future  :  futures)  {                results.add(future.get());              }                    }  finally  {              service.shutdown();            }                  for  (Integer  res:  results){              System.out.println("\nGot  the  result:  "  +  res);        }      }        }  

Page 19: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

Walkthrough  3  

•  Review  the  code  of  the  TestCallableThreads  form  the  Lesson21  project.  Run  the  examples  and  observe  the  results.    

•  Change  the  code  of  the  thread  PorholioCallable  as  follows:    a)  Its  constructor  should  have  an  argument  to  receive  the  price  of  the  IBM  stock:  double  price  

                     b)  The  thread  should  return  the  total  amount  based  on  the                      price  mulEplied  by  504.              c)  Change  the  code  of  the  TestCallableThreads  to  pass  164.22                      as  the  price  of  IBM                d)  Run  and  the  TestCallableThreads  and  observe  the  results          

(c)  Farata  Systems,  L.L.C.    2011  

Page 20: JavaProgramming$$ Unit11$myflex.org/yf/java/Unit11_threads_part2.pdf · WaitNoEfy$Code$Sample$ (c)$FarataSystems,$L.L.C.$$2011$ class$ClassA{$String$marketNews$=null;$ $ void someMethod(){$

Homework  1.  Study  the  materials  from  the  lessons  20  and  21  (up  to  the  Concurrent  CollecEons  secEon  )  from  the  textbook.      2.  Do  the  assignment  from  the  TRY  IT  secEon  of  Lessons  20.    Addi/onal  materials  for  the  in  depth  understanding  of  Java  concurrency:    Read  the  tutorial  by  Jakob  Jenkov  on  Java  concurrency:  htp://tutorials.jenkov.com/java-­‐concurrency/index.html      Study  the  presentaEon  and  project  of  Viktor  Grazi,    “Concurrency  Animated”  :  htp://sourceforge.net/projects/javaconcurrenta/      The  most  advanced  book  on  the  subject  is  “Java  Concurrency  in  PracEce”  by  Brian  Goetz  et  al.  

(c)  Farata  Systems,  L.L.C.    2011