c3#vniculescu/didactic/pp/... · 2020. 10. 22. · c3# procese,#thread/uri, taskuri# concurenta#...

59
C3 Procese, Threaduri, Taskuri Concurenta Java Threads Pradigme si Tehnici ale programarii paralele 1

Upload: others

Post on 14-Feb-2021

1 views

Category:

Documents


0 download

TRANSCRIPT

  • C3  

    Procese,  Thread-‐uri,  Taskuri  Concurenta  Java  Threads  

    Pradigme  si  Tehnici  ale  programarii  paralele   1  

  • Concurenta  

    •  Concurrency:  –  Mul?processing  –  Mul?tasking    –  Any  combina?on  of  them  

    •  Probleme  -‐>  termeni  –  race  condi?ons,  deadlock,  starva?on,…  

    Pradigme  si  Tehnici  ale  programarii  paralele   2  

  • Mul?processing  -‐>  Paralelism    

    •  Mul?core  processors  

    •  Se  folosesc  mai  multe  unita?  de  procesare  •  Procesele  se  executa  in  acelasi  ?mp  

    Pradigme  si  Tehnici  ale  programarii  paralele   3  

  • Mul?tasking-‐>  Concurenta  

    •  Sistemul  de  operare  schimba  execu?a  intre  diferite  taskuri  

    •  Interleaving  –   sunt  mai  multe  taskuri  ac?ve,  dar  doar  unul  se  executa  la  un  moment  dat  

    •  Mul?tasking:    –  SO  ruleaza  execu?i  intretesute  

    Pradigme  si  Tehnici  ale  programarii  paralele   4  

  • Procese  

    •  Un  program  (secven?al)  =  un  set  de  instruc?uni  –  (in  pradigma  programarii  impera?ve)  

    •  Un  proces    =  o  instanta  a  unui  program  care  se  executa  

    Pradigme  si  Tehnici  ale  programarii  paralele   5  

  • Procese  in  sisteme  de  operare  

    •  Structura  unui  proces  –  Iden?ficator  de  proces    (ID)  –  Starea  procesului    (ac?vitatea  curenta)  –  Contextul  procesului  (valori  registrii,  program  counter)  –  Memorie  (codul  program,  date  globale,  s?va  si  heap)  

    Pradigme  si  Tehnici  ale  programarii  paralele   6  

  • Scheduler  

    •  Un  program  care  controleaza  execu?a  proceselor  –  Seteaza  starile  procesului  

    •  new  •  running  •  blocked  (nu  poate  fi  selectat  pt  execu?e;  este  nevoie  de  un  event  extern  pt  a  iesi  din  aceasta  stare)  •  ready  •  terminated  

    Pradigme  si  Tehnici  ale  programarii  paralele   7  

  • Pradigme  si  Tehnici  ale  programarii  paralele   8  

  • Context  switch  

    •  Atunci  cand  OS  scheduler  schimba  procesul  executat  de  o  unitate  de  procesare  

    •  Ac?uni  asociate:  –  P1.state  :=  ready  –  Se  salveaza  valoarea  registrilor  in  memorie  ca  si  context  al  lui  P1  –  Se  foloseste  contextul  lui  P2  pt  a  seta  registrii  –  P2.state  :=  running  

    Pradigme  si  Tehnici  ale  programarii  paralele   9  

  • Threads  

    •  Un  thread  este  o  parte  a  unui  proces  al  sistemului  de  operare  •  Componente  private  fiecarui  thread:  

    –  Iden?ficator  –  Stare  –  Context  –  Memorie  (doar  s?va)  

    •  Componente  partajate  cu  alte  thread-‐uri    –  Cod  program  –  Date  globale  –  Heap  

    Pradigme  si  Tehnici  ale  programarii  paralele   10  

  • Concurenta  cu  Threads    

    Program  concurent:  un  program  care  la  execu?e  conduce  la  un  proces  care  con?ne  mai  multe  threaduri  

    Pradigme  si  Tehnici  ale  programarii  paralele   11  

  • Variante  de  execu?e  

    •  Secvente  de  execu?e  

    Pradigme  si  Tehnici  ale  programarii  paralele   12  

  • Race  condi?on  &  Cri?cal  sec?on  

    •  Procese  /  threaduri  independente  =>  execu?e  simpla  fara  probleme  

    •  Daca  exista  interac?une  (ex.  Accesarea  si  modificarea  acelasi  variabile)  =>  pot  apare  probleme  

    •  Nondeterminis+c  interleaving  

    •  Daca  rezultatul  depinde  de  interleaving    =>  race  condi7on  (data  race)  

    •  Pot  fi  erori  extrem  de  greu  de  depistat!!!  

    •  O  sec?une  de  cod  care  conduce  la  o  condi?e  de  ?p  race  condi+on  este  numita  sec$une  cri$ca  (cri7cal  sec7on)  

    Pradigme  si  Tehnici  ale  programarii  paralele   13  

  • Instruc?uni  atomice  

    •   este  atomica  daca  execu?a  sa  nu  poate  fi  “interleaved”  cu  cea  a  altei  instruc?uni  inainte  de  terminarea  ei.  

    •  Niveluri  de  atomicitate  

    Ex:      x:=  x  +  1  Execu?e:  

    temp := x LOAD REG, x

    temp := temp + 1 ADD REG, #1

    x := temp STORE REG, x

       

    Pradigme  si  Tehnici  ale  programarii  paralele   14  

  • Variante  de  execu?e  

    •  exemplul  anterior  

    •  o  execu?e  "interleaving"  

    Pradigme  si  Tehnici  ale  programarii  paralele   15  

  • Thread  Safety  vs  Shared  Resources  

    •  Un  cod  pentru  care  este  sigur  apelul  simultan  de  catre  mai  multe  thread-‐uri  –  indiferent  de  posibila  execu?e  intretesuta  -‐  se  numeste  cod  thread  safe.    

    •  Daca  un  cod  este  thread  safe,  atunci  sigur  nu  con?ne  race  condi+ons.    

    •  O  condi?e  de  ?p  race  condi7on    apare  doar  atunci  cand  mai  multe  threaduri  actualizeaza  o  resursa  comuna.  

    Pradigme  si  Tehnici  ale  programarii  paralele   16  

  • Threads      

         Java  

    Pradigme  si  Tehnici  ale  programarii  paralele   17  

  • Java  threads  

    Pradigme  si  Tehnici  ale  programarii  paralele   18  

    public  class  HelloRunnable  implements  Runnable  {    

    public  void  run()  {      System.out.println("Hello  from  a  

    thread!");    }      public  sta?c  void  main  (String  args[])  {    

     (new  Thread  (new  HelloRunnable())).start();    ……..  }  

     }    

    public  class  HelloThread  extends  Thread  {    public  void  run()  {    

     System.out.println("Hello  from  a  thread!");    }      public  sta?c  void  main(String  args[])  {    

     (new  HelloThread()).start();    ………..  }    

    }        

  • Main  Thread  

    •  When  a  Java  Virtual  Machine  starts  up,  there  is  usually  a  single  non-‐daemon  thread  (which  typically  calls  the  method  named  main  of  some  designated  class).  

    •   The  Java  Virtual  Machine  con?nues  to  execute  threads  un?l  either  of  the  following  occurs:  

    –  The  exit  method  of  class  Run?me  has  been  called  and  the  security  manager  has  permioed  the  exit  opera?on  to  take  place.  

     –  All  threads  that  are  not  daemon  threads  have  died,  either  by  returning  from  

    the  call  to  the  run  method  or  by  throwing  an  excep?on  that  propagates  beyond  the  run  method.  

    Pradigme  si  Tehnici  ale  programarii  paralele   19  

  • Java  Thread  State  (public  Thread.State  getState())  

    public  sta$c  enum  Thread.State  extends  Enum  A  thread  state.  A  thread  can  be  in  one  of  the  following  states:  NEW  A  thread  that  has  not  yet  started  is  in  this  state.  RUNNABLE  A  thread  execu?ng  in  the  Java  virtual  machine  is  in  this  state.  BLOCKED  A  thread  that  is  blocked  wai?ng  for  a  monitor  lock  is  in  this  state.  WAITING  A  thread  that  is  wai?ng  indefinitely  for  another  thread  to  perform  a  par?cular  ac?on  is  in  this  state.  TIMED_WAITING  A  thread  that  is  wai?ng  for  another  thread  to  perform  an  ac?on  for  up  to  a  specified  wai?ng  ?me  is  in  this  state.  TERMINATED  A  thread  that  has  exited  is  in  this  state.    

    Pradigme  si  Tehnici  ale  programarii  paralele   20  

  • 21  

    Thread  control    

    •  join()  wait  for  thread  to  finish    

    •  sleep(int  n)  sleep  for  n  ms  (keep  locks)    •  interrupt()  send  signal  to  interrupt  a  sleeping  or  wai?ng  thread    •  yield()  suggest  another  can  run    

    Pradigme  si  Tehnici  ale  programarii  paralele  

  • 22  

    Race  Condi7ons  &  Cri7cal  Sec7ons  

    •  Situa?a  in  care  2  sau  mai  multe  threaduri  se  "lupta”  pentru  o  resursa  comuna    (ex.  variabila)  este  de  ?p  race  condi+on.  

    •   O  sec?une  de  cod  care  conduce  la  o  condi?e  de  ?p  race  condi+on  este  numita  sec$une  cri$ca  (cri7cal  sec7on).    

    public  class  Counter  {            protected  long  count  =  0;            public  void  add(long  value){                    this.count  =  this.count  +  value;                  }      }  

    Pradigme  si  Tehnici  ale  programarii  paralele  

  • 23  

    Variabile  locale  

    •  Variabilele  locale  din  thread-‐uri  sunt  stocate  pe  s+va  fiecarui  thread.    •  Nu  sunt  partajate.  •  Prin  urmare  toate  variabilele  primi?ve  locale  sunt  thread  safe.  

    Ex:    public  void  someMethod(){      long  threadSafeInt  =  0;      threadSafeInt++;  }  

    Pradigme  si  Tehnici  ale  programarii  paralele  

  • 24  

    Referinte  Locale  

    •  Referintele  nu  sunt  partajate  (orice  obiect  este  accesibil  printr-‐o  referinta).    •  Obiectul  referit  este  partajat  (shared  heap).    •  Daca  un  obiect  creat  local  nu  se  foloseste  decat  local  in  metoda  care  il  creeaza  

    atunci  este  thread  safe.    •  Daca  un  obiect  creat  local  este  transferat  altor  metode  dar  nu  este  transferat  altor  

    threaduri  atunci  este  thread  safe.    

    Ex:    public  void  someMethod(){      LocalObject  localObject  =  new  LocalObject();      localObject.callMethod();      method2(localObject);  }  public  void  method2(LocalObject  localObject){      localObject.setValue("value");  }  

    Pradigme  si  Tehnici  ale  programarii  paralele  

  • 25  

    Exemplu:  not  thread  safe  

    public  class  NotThreadSafe{            StringBuilder  builder  =    new  StringBuilder();            public  add(String  text){                  this.builder.append(text);          }    }  ///////////////////////////////////////////////////  public  class  MyRunnable  implements  Runnable{      NotThreadSafe  instance  =  null;            public  MyRunnable(NotThreadSafe  instance){          this.instance  =  instance;      }        public  void  run(){          this.instance.add("some  text");      }  }    

    NotThreadSafe  sharedInstance  =  new  NotThreadSafe();  

     new  Thread(new  

    MyRunnable(sharedInstance)).start();      new  Thread(new  

    MyRunnable(sharedInstance)).start();    

    Pradigme  si  Tehnici  ale  programarii  paralele  

  • 26  

    Shared  Variables  

    •  shared  memory  (heap  memory).    

    •  Toate  atributele  claselor  ,  campurile  sta?ce  si  elementele  tablourilor  sunt  stocate  in  heap  è  shared.    

    •  Doua  opera?i  de  acces  (read  or  write)    la  aceeasi  variabila  se  spune  ca  sunt  in  conflict  daca  cel  pu?n  unul  este  scriere  (write).    

    Pradigme  si  Tehnici  ale  programarii  paralele  

  • Thread-‐Safe  shared  variables  

    •  Daca  mai  multe  thread-‐uri  folosesc  o  variabila  mutabila(modificabila)  fara  sa  foloseasca  sincronizari  codul  nu  este  safe.  

     •  Solu?i:  

    –  eliminarea  partajarii  valorii  variabilei  intre  threaduri  –  transformarea  variabile  in  variabila–imutabila  (var  imutabile  sunt  thread-‐safe)  –  sincronizarea  accesului  la  starea  variabilei  

    Pradigme  si  Tehnici  ale  programarii  paralele   27  

  • Thread-‐safe  classes    

    •  Thread-‐safe  class    

    –  daca  comportamentul  instantelor  sale  este  corect  chiar  daca  este  accesat  din  threaduri  mul?ple  indiferent  de  execu?a  intretesuta  a  lor(interleaving)    fara  sa  fie  nevoie  de  sincronizari  adi?onale  sau  alte  condi?i  impose  codului  apelant.  

     –  sincronizarile  sunt  incapsulate  in  interior  si  asvel  clien?i  clasei  nu  trebuie  sa  

    foloseasca  altele  speciale.  

    Pradigme  si  Tehnici  ale  programarii  paralele   28  

  • 29

    Variabile locale / globale

    •  instance fields, | •  static fields, and | •  array elements | => heap memory.

    Ø  local variables, | Ø  method parameters, and | Ø  exception handler parameters |=> local for each thread (stack)

  • 30

    Synchronization

    •  monitors •  Lock or unlock.

    •  synchronized statement •  synchronized methods

  • 31

    fine-grained synchronization

    public class Counter { private long c1 = 0; private long c2 = 0; private Object lock1 = new Object(); private Object lock2 = new Object(); public void inc1() { synchronized(lock1) { c1++; } } public void inc2() { synchronized(lock2) { c2++; } } }

    • Ce se intampla daca lock1 sau lock2 se modifica?

  • 32

    Exemplu

    public class SynchronizedCounter { private int c = 0; public synchronized void increment() { c++; } public synchronized void decrement() { c--; } public synchronized int value() { return c; } }

  • 33

    Variabile volatile

    •  –  valoarea variabile nu va fi niciodata salvata local (cached thread-

    locally) –  toate citirile scrierile => "main memory"; –  efect similar synchronized block. –  nu se executa nici o blocare mutual exclusiva.

  • 34

    Wait si Notify

    •  Fiecare obiect are pe langa un monitor asociat si o multime - wait set. –  multime de thread-uri.

    •  atunci cand un obiect se creeaza aceasta multime e vida. Modificari se produc in urma apelurilor metodelor: –  Object.wait –  Object.notify –  Object.notifyAll

    •  Wait set poate fi afectata de "interruption status" a unui thread si de catre metodele care opereaza intreruperi.

    •  In plus, metodele sleep si join ale altor threaduri au proprietati derivate din

    acelea ale actiunilor de asteptare si notificare.

  • 35

    Wait

    •  –  wait(), –  wait(long millisecs) –  wait(long millisecs, int nanosecs).

    •  Un thread "returns normally" dintr-o asteptare daca nu arunca o expectie de tip InterruptedException.

  • 36

    Mecanism detaliat

    •  Fie threadul t care executa o metoda wait pe obiectul o, –  fie n = numarul de actiuni de blocare ale lui t pe o pt care nu au existat

    operatii pereche de deblocare. Atunci:

    –  Daca n =0, atunci se arunca IllegalMonitorStateException. Acesta este cazul in care t nu poseda inca blocarea pe o.

    –  Daca wait este de tip timed wait si argumentul nu este in intervalul

    0-999999 sau este negativ, atunci se arunca llegalArgumentException. –  Daca t este interrupted, atunci se arunca InterruptedException si

    interruption status pentru t este setat la false.

  • 37

    Altfel exista urm. situatii 1.  Thread-ul t este adaugat multimii wait set pentru obiectul o si executa n

    deblocari pe o. Atunci:

    Thread-ul t nu executa alte instructiuni pana cand nu este sters din wait set al lui o. Thread-ul t poate fi sters din wait set al lui o ca urmare a uneia din urm. actiuni (si apoi isi va relua executia) :

    ◆ O actiune notify asupra lui o in care t este selectat spre a fi sters din wait set. ◆ O actiune notifyAll asupra lui o . ◆ O actiune de intrerupere realizata de t. ◆ Trecerea timpului (argument) specificat la apelul lui wait. ◆ Operatii "spurious wake-ups" – nerecomandate/rare.

  • 38

    Conditii

    •  folosirea operatiilor wait doar in cicluri care se termina atunci cand anumite conditii logice sunt indeplinite.

    •  fiecare thread trebuie sa determine o ordine intre evenimentele care pot cauza ca el sa fie sters din wait set.

    De exemplu: daca t este in wait set pt o, atunci cand apare atat o intrerupere

    a lui t cat si o notificare a lui o, trebuie sa existe o ordine intre aceste evenimente.

    ÷  Daca interrupt este considerata prima, atunci pana la urma t iese din wait aruncand InterruptedException, si alt thread din wait set a lui o (daca mai exista vreunul) va primi notificarea.

    ÷  Daca sunt invers ordonate atunci t iese normal din wait si intreruperea este in asteptare (pana se verifica starea).

  • 39

    2. Thread-ul t executa n operatii de deblocare pe o. 3. Daca thread t a fost sters din wait set a lui o din cauza unei intreruperi atunci

    interruption status al lui t este setat la false si se iese din wait cu aruncarea unei exceptii de tip InterruptedException.

  • 40

    Notification

    •  no$fy    •  no$fyAll  

    •  Fie  threadul  t  executa  una  dintre  cele  2  metode  pe  obiectul  o,  •  fie  n  =  numarul  de  opera7i  de  blocare  a  lui  t  care  nu  s-‐au  potrivit  cu  ac7uni  de  deblocare.  Una  dintre  urm.  ac?uni  apare:  

    –  Daca  n  =0,  atunci  se  arunca  o  excep?e  IllegalMonitorStateExcep?on.  Acesta  este  cazul  in  care  t  nu  poseda  nici  un  lock  pe  o.  –  Daca  n>0  si    este  o  ac?une  no$fy  si  wait  set    a  lui  o  nu  e  vida  atunci  un  thread  u  care  

    este  inclus  in  wait  set    a  lui  o    este  selectat  si  sters  din  acea  mul?me.  Aceasta  stergere  permite  resuscitarea  lui  u  din  ac?unea  de  asteptare.  Totusi  ac?unile    lui  u  nu  pot  reusi  mai  devreme  ca  t  sa  deblocheze  complet  monitorul  lui  o.  

    (Nu  exista  nici  o  garan?e  ca  un  anumit  thread  sau  altul  va  fi  ales.)  –  Daca  n>0  si    este  o  ac?une  no$fyAll  atunci  toate  threadurile  sunt  sterse  din  wait  set    a  

    lui  m.  

    •  Totusi  doar  unul  va  debloca  monitorul  atunci  cand  va  iesi  din  wait.  

  • 41

    Interruptions

    •  Actiunile Interruption actions occur upon invocation of Thread.interrupt, as well as methods defined to invoke it in turn, such as ThreadGroup.interrupt.

    •  Let t be the thread invoking u.interrupt, for some thread u, where t and u may be the same. This action causes u's interruption status to be set to true.

    •  Additionally, if there exists some object o whose wait set contains u, then u is removed from m's wait set. This enables u to resume in a wait action, in which case this wait will, after re-locking m's monitor, throw InterruptedException.

    •  Invocations of Thread.isInterrupted can determine a thread's interruption status. The static method Thread.interrupted may be invoked by a thread to observe and clear its own interruption status.

  • 42

    Intreruperi

    •  mecanismul de intrerupere foloseste un flag intern -> the interrupt status.

    •  Atunci cand se apeleaza Thread.interrupt se seteaza acest flag.

    •  Atunci cand se verifica intreruperea prin metoda statica Thread.interrupted, este sters.

    •  Metoda nestatica isInterrupted, care este folosita de catre un thread pt a verifica statusul (interrupt status) al altuia nu schimba flagul.

    •  Prin conventie, orice metoda care se termina (exit) aruncand o exceptie de tip InterruptedException sterge "interrupt status".

    •  Totusi este posibil ca acesta sa fie imediat setat din nou de catre alt thread care invoca o metoda interrupt.

  • 43

    Exemplu public class SimpleThreads { static void threadMessage(String message) { String threadName = Thread.currentThread().getName(); System.out.format("%s: %s %n", threadName, message); } private static class MessageLoop implements Runnable { public void run() { String importantInfo[] = { "Mares eat oats", "Does eat oats", "Little lambs eat ivy", "A kid will eat ivy too" }; try { for (int i = 0; i < importantInfo.length; i++) { // Pause for 4 seconds Thread.sleep(4000); // Print a message threadMessage(importantInfo[i]); } } catch (InterruptedException e) { threadMessage("I wasn't done!"); } } }

  • 44

    public static void main(String args[]) throws InterruptedException { // Delay, in milliseconds before // we interrupt MessageLoop // thread (default one hour). long patience = 1000 * 60 * 60; // If command line argument present,

    // gives patience in seconds. if (args.length > 0) { try { patience = Long.parseLong(args[0]) * 1000; }

    catch (NumberFormatException e) { System.err.println("Argument must be an

    integer."); System.exit(1);

    } }

    threadMessage("Starting MessageLoop thread"); long startTime = System.currentTimeMillis(); Thread t = new Thread(new MessageLoop()); t.start(); threadMessage("Waiting for MessageLoop thread to

    finish"); while (t.isAlive()) { threadMessage("Still waiting...");

    t.join(1000); if (((System.currentTimeMillis() - startTime) >

    patience) && t.isAlive()) { threadMessage("Tired of waiting!"); t.interrupt(); // Shouldn't be long now // -- wait indefinitely t.join(); } } threadMessage("Finally!"); } }

  • 45

    Interactiuni intre Waits, Notification, si Interruption

    •  Notificarile nu se pot perde din cauza intreruperilor.

    •  Presupunem ca un set de threaduri s este in wait set a lui o, si alt thread executa notificare pe o.

    Atunci fie: –  cel putin un thread din s iese normal din wait, sau –  toate threadurile din s ies din wait aruncand exceptie InterruptedException

    •  Daca un thread este atat intrerupt cat si trezit prin notificare si el iese din wait aruncand o exceptie si atunci un alt thread din wait set va fi notificat.

  • 46

    Exemplu public class Producer extends Thread { private CubbyHole cubbyhole;

    // shared data private int number; public Producer(CubbyHole c, int number)

    { cubbyhole = c; this.number = number; } public void run() { for (int i = 0; i < 10; i++) { cubbyhole.put(i);

    // Accesses shared data System.out.println("Producer #" +

    this.number + " put: " + i); try { sleep((int)(Math.random() * 100)); } catch (InterruptedException e) { } } } }

    public class Consumer extends Thread { private CubbyHole cubbyhole;

    // shared data private int number; public Consumer(CubbyHole c, int

    number) { cubbyhole = c; this.number = number; } public void run() { int value = 0; for (int i = 0; i < 10; i++) { value = cubbyhole.get();

    // Accesses shared data System.out.println("Consumer #" +

    this.number + " got: " + value); } } }

  • 47

    public class CubbyHole { private int contents; // shared data private boolean available = false; /* Method used by the consumer to access the shared data */ public synchronized int get() { while (available == false) { try { wait(); // Consumer enters a wait state until notified by the Producer } catch (InterruptedException e) { } } available = false; notifyAll(); // Consumer notifies Producer that it can store new contents return contents; } /* Method used by the producer to stor the shared data */ public synchronized void put (int value) { while (available == true) { try { wait(); // Producer who wants to store contents enters

    // a wait state until notified by the Consumer } catch (InterruptedException e) { } } contents = value; available = true; notifyAll(); // Producer notifies Consumer to come out

    // of the wait state and consume the contents } }

  • 48

    exemplu: BlockingQueue

    /** Extend Queue to make threads block until remove has * data. */ class BlockingQueue { int n = 0; Queue data = ...; public synchronized Object remove() { // wait until there is something to read while (n==0) this.wait(); // we have the lock and state we're seeking n--; // return data element from queue } public synchronized void write(Object o) { n++; // add data to queue // have data. tell any waiting threads to wake up notifyAll(); } }

  • 49  

    Java  vola?le  keyword    

    •  vola?le  –  indica  faptul  ca  o  variabila  va  fi  modificata  de  mai  multe  thread-‐uri.  

    •  Efect:    –  Valoarea  variabilei  nu  va  fi  cached  thread-‐locally:  toate  ci?rile  si  scrierile  se  

    vor  face  direct  in  "main  memory"(heap);      –  Accesul  la  variabila  este  ca  si  cum  ar  fi  inclus  intr-‐o  sec?une  sincronizata  

    (monitor  al  variabilei  insasi)  .    –  se  garanteaza  accesul  sincronizat    –  volatile  nu  va  face  nici  o  blocare  mutual  recursiva  asupra  variabilei.  

    Pradigme  si  Tehnici  ale  programarii  paralele  

  • 50  

    Vola?le  

    •  se  garanteaza  ca  orice  thread  va  ci?  ul?ma  valoare  a  campului  v  (cea  mai  recenta  modificare  a  sa).  

    •  Din  versiunea  Java  5  sunt  vizibile  si  toate  efectele  colaterale  (side  effects).    

    è  accesul  (write)  la  o  variabila  vola?la  va  actualiza  si  variabilele  non-‐vola?le  care  au  fost  modificate  de  acelasi  thread.    

    class  Vola$leExample  {      int  x  =  0;      vola$le  boolean  v  =  false;        public  void  writer()  {          x  =  42;          v  =  true;      }        public  void  reader()  {          if  (v  ==  true)  {              //uses  x  -‐  guaranteed  to  see  42.          }      }  }  

    Pradigme  si  Tehnici  ale  programarii  paralele  

  • 51  

    Exemplu  

       

    public class Singleton{ private static volatile Singleton _instance; //volatile variable public static Singleton getInstance(){ if(_instance == null){

    synchronized(Singleton.class){

    if(_instance == null) _instance = new Singleton();

    } } return _instance; }    

    Fara  vola?le  atunci  thread  A  nu  s?e  ca  thread  B  ar  putea  accesa  variabila.  Asvel  thread  A  considera  ok  sa    foloseasca  o  copie  (cache  the  value)  intr-‐un  registru  sau  in  memoria  locala  è  probleme    

    Pradigme  si  Tehnici  ale  programarii  paralele  

  • 52  

    public  class  StoppableTask  extends  Thread  {      private  vola$le  boolean  pleaseStop;        public  void  run()  {          while  (!pleaseStop)  {              //  do  some  stuff...          }      }      public  void  tellMeToStop()  {          pleaseStop  =  true;      }  }  

    Fara  vola?le:  -‐  threadul  care  executa  ciclul  poate  sa  copieze  (cache)  the  variabila  pleaseStop    la  

    inceputul  ciclului  si  sa  nu  o  mai  citeasca  din  nou.    

    Exemplu  

    Pradigme  si  Tehnici  ale  programarii  paralele  

  • 53  

    Atomic  Access  

    •  atomic  ac?on    –  se  executa  fie  complet  fie  deloc  –  pana  cand  nu  se  termina  nu  sunt  vizibile  nici  un  fel  de  side  effects  (modificari).  

    •  in  general  o  simpla  incrementare  nu  este  o  ac?une  atomica.      Se  pot  insa  specifica  ac?uni  atomice  :  

    –  Reads  /writes  pt  variabile  referinta  si  pentru  var    primi?ve  cu  excep?a  celor  de  ?p  long  si  double.    

    –  Reads  /  writes  a  pt  toate  variabilele  declarate  vola$le  (inclusiv  cele  de  7p    long  si  double)    

    •  Folosirea  variabilelor  vola?le  reduce  riscul  de  a  se  ajunge  la  erori  de  consistenta  a  memoriei  (dar  nu  le  exclud).    

    •  Modificarea  unei  variabile  vola?le  este  vizibila  celorlalte  threaduri.  

    Pradigme  si  Tehnici  ale  programarii  paralele  

  • 54  

    Diferente  intre  synchronized  si  vola?le  

    –  o  variabila  primi?va  poate  fi  declarata  vola?le    –  nu  se  poate  folosi    synchronized  pe  o  variabila  primi?va;    

    –  accesul  la  o  variabila  vola?le  nu  are  poten?al  de  blocare  (niciodata);    

    –  pentru  ca  accesul  la  o  var  vola?le  nu  implica  o  blocare  nu  este  potrivit  pentru  cazurile  in  care  dorim  ac?uni  de  ?p  read-‐update-‐write  sa  fie  tratate  ca  si  opera?i  atomice;    

    –  o  var  vola?le  care  este  referinta  la  un  obiect  poate  fi  nula  (se  asigura  accesul  atomic  la  referinta  nu  la  obiectul);    

    –  incercarea  de  a  sincroniza  un  obiect  null  è  throw    NullPointerExcep?on.  

    Pradigme  si  Tehnici  ale  programarii  paralele  

  • Sincronizare  

    •  Pentru  a  se  rezolva  problemele  legate  de  "race  condi?ons"  execu?a  procesele  se  sincronizeaza.  

    •  Sincronizarea  implica  faptul  ca  procesele  agreeaza  impreuna  o  secventa  de  ac?uni.  

    •  Exemple:  –  doar  un  proces  poate  sa  foloseasca  o  resursa  la  un  moment  dat  (exclusive  use)  –  un  proces  se  executa  doar  daca  altul  s-‐a  executat  anterior  

    Pradigme  si  Tehnici  ale  programarii  paralele   55  

  • Comunicare  intre  procese  

    •  Shared  memory  –  se  scriu  si  se  citesc  date  in  sec?unile  partajate  ale  memoriei  

    (Pentru  thread-‐uri  doar  acest  ?p  de  comunicare  se  aplica.)  

    •  Distributed  memory  –  transmitere  de  mesaje  (send,  receive,  ...)  

    Pradigme  si  Tehnici  ale  programarii  paralele   56  

  • Safety  -‐  Liveness  

    •  Safety  –  "nothing  bad  ever  happens"  

    •  Liveness  –  "something  good  eventually  happens"  

    Pradigme  si  Tehnici  ale  programarii  paralele   57  

  • Deadlock  –  Starva?on  -‐-‐  Fairness  

    •  Deadlock  –  situa?a  in  care  un  grup  de  procese  se  blocheaza  la  infinit  pentru  ca  fiecarea  proces  

    asteapta  dupa  o  resursa  care  este  re?nuta  de  alt  proces  care  la  randul  lui  asteapta  dupa  alta  resursa.  

    •  Starva+on    –  situa?a  in  care  accesul  este  mereu  refuzat  

    •  Fairness  –  presupune  o  rezolvare  corecta  a  nedeterminismului  in  execu?e  –  Weak  fairness    

    •  daca  o  ac?une  este  in  mod  con?nuu  accesibila(con7nuously  enabled)(stare-‐ready)  atunci  trebuie  sa  fie  executata  infinit  de  des  (infinetely  oIen).  

    –  Strong  fairness  •  daca  o  ac?une  este  infinit  de  des  accesibilila  (unfinetely  oIen  enabled)  dar  nu  

    obligatoriu  in  mod  con?nuu  atunci  trebuie  sa  fie  executata  infinit  de  des  (infinetely  oIen).  

    Pradigme  si  Tehnici  ale  programarii  paralele   58  

  • Semafoare:  avantaje  -‐  dezavantaje  

    Semafoarele      –  primi?va  de  sincronizare    -‐  conceptual  –  simpla,  eficienta  si  versa?la  

     Se  poate  considera  ca  semafoarele  furnizeaza  "prea  multa"  flexibilitate:  

    –  Nu  se  poate  determina  u?lizarea  corecta  a  semafoarelor  doar  din  bucata  de  cod  unde  ele  apar;-‐  e  posibil  ca  intreg  codul  sa  fie  nevoie  a  fi  evaluat  

    –  daca  se  uita  sau  se  pozi?oneaza  incorect  o  opera?e  (V  sau  P)  se  compromite  corec?tudinea;  

    –  e  usor  sa  se  ajunga  la  deadlock  atunci  cand  se  folosesc  (dificil  de  depanat).  

    Pradigme  si  Tehnici  ale  programarii  paralele   59