49
Curs 7 Programare Paralela si Distribuita Forme de sincronizare:Bariera de sincronizare/Rendez-vous Variabile ThreadLocal Intreruperi Exchanger Curs 7 - PPD - 1

Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Curs 7Programare Paralela si Distribuita

Forme de sincronizare:Bariera de sincronizare/Rendez-vousVariabile ThreadLocalIntreruperi

Exchanger

Curs 7 - PPD - 1

Page 2: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Bariera de sincronizare

Curs 7 - PPD - 2

CyclicBarrier barrier = new CyclicBarrier(2);// 2 = no_of_threads_to_wait_for

barrier.await();

barrier.await(10, TimeUnit.SECONDS);

Bariera de sincronizare:

- Bariera secventiala – pt implementarese fol. in general 2 variabile –{no_threads(0..n), state(stop/pass)}

- Bariera ierarhica (tree-barrier)

Jacob Jenkov Tutorial

Page 3: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

java.util.concurrent.CyclicBarrier(java documentation)

• A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other.

• The barrier is called cyclic because it can be re-used after the waiting threads are released.

• A CyclicBarrier supports an optional Runnable command that is run once per barrier point, after the last thread in the party arrives, but before any threads are released. This barrier action is useful for updating shared-state before any of the parties continue.– CyclicBarrier(int parties)– CyclicBarrier(int parties, Runnable barrierAction)

Curs 7 - PPD - 3

Page 4: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

java.util.concurrent.CountDownLatch(java documentation)

• A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

• A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero due to invocations of the countDown() method, after which all waiting threads are released and any subsequent invocations of await return immediately. – This is a one-shot phenomenon -- the count cannot be reset. If you need a version that

resets the count, consider using a CyclicBarrier.

• A CountDownLatch is a versatile synchronization tool and can be used for a number of purposes. – A CountDownLatch initialized with a count of one serves as a simple on/off latch, or

gate: all threads invoking await wait at the gate until it is opened by a thread invoking countDown().

– A CountDownLatch initialized to N can be used to make one thread wait until N threads have completed some action, or some action has been completed N times.

• A useful property of a CountDownLatch is that it doesn't require that threads calling countDown wait for the count to reach zero before proceeding, it simply prevents any thread from proceeding past an await until all threads could pass.

Curs 7 - PPD - 4

Page 5: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

CountDownLatch (Java)

final CountDownLatch latch = new CountDownLatch(5);

// making two threads for 2 servicesThread serviceOneThread = new Thread(new ServiceOne(latch, 2));Thread serviceTwoThread = new Thread(new ServiceTwo(latch, 3));

serviceOneThread.start();serviceTwoThread.start();

// latch waits till the count becomes 0// this way it can make sure that the execution of main thread only// finishes once 2 services have executedtry {

latch.await(); …

Curs 7 - PPD - 5

Page 6: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Conceptul de intalnire (rendez-vous)

• Conceptul de întâlnire (rendez-vous) a fost introdus initial in limbajul Ada pentru a facilita comunicarea între două task-uri.

a) Procesul B este gata să transmită informaţiile, dar procesul A nu le-a cerut încă. In acest caz, procesul B rămâne în aşteptare până când procesul A i le cere.

b) Procesul B este gata să transmită informaţiile cerute, iar procesul A cere aceste date. In acest caz, se realizează un rendez-vous, cele două procese lucrează sincron până când îşi termină schimbul, după care fiecare îşi continuă activitatea independent.

c) Procesul A a lansat o cerere, dar procesul B nu este în măsură să-i furnizeze informaţiile solicitate. In acest caz, A rămâne în aşteptare până la întâlnirea cu B.

Curs 7 - PPD - 6

Page 7: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Java Exchanger <-> Rendez-Vous

Curs 7 - PPD - 7

Thread-0 exchanged A for BThread-1 exchanged B for A

Jacob Jenkov Tutorial

Page 8: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Exchanger(java doc)

public V exchange(V x) throws InterruptedException

• Waits for another thread to arrive at this exchange point (unless the current thread is interrupted), and then transfers the given object to it, receiving its object in return.

• If another thread is already waiting at the exchange point then it is resumed for thread scheduling purposes and receives the object passed in by the current thread. – The current thread returns immediately, receiving the object passed to the exchange by

that other thread.

If no other thread is already waiting at the exchange then the current thread is disabled for thread scheduling purposes and lies dormant until one of two things happens:• Some other thread enters the exchange; or• Some other thread interrupts the current thread.

If the current thread:• has its interrupted status set on entry to this method; or• is interrupted while waiting for the exchange,

– then InterruptedException is thrown and the current thread's interrupted status is cleared.

Curs 7 - PPD - 8

Page 9: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Curs 7 - PPD - 9

Exchanger exchanger = new Exchanger();

ExchangerRunnable exchangerRunnable1 = new ExchangerRunnable(exchanger, "A");

ExchangerRunnable exchangerRunnable2 = new ExchangerRunnable(exchanger, "B");

new Thread(exchangerRunnable1).start();new Thread(exchangerRunnable2).start();

Page 10: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Curs 7 - PPD - 10

public class ExchangerRunnable implements Runnable{Exchanger exchanger = null;Object object = null;

public ExchangerRunnable(Exchanger exchanger, Object object) {this.exchanger = exchanger;this.object = object;

}

public void run() {try {

Object previous = this.object;this.object = this.exchanger.exchange (this.object);

System.out.println(Thread.currentThread().getName() +" exchanged " + previous + " for " + this.object

);} catch (InterruptedException e) {

e.printStackTrace();}

}}

Page 11: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Class SynchronousQueue (->Rendez-vous)Java doc

java.lang.Objectjava.util.AbstractCollection<E>

java.util.AbstractQueue<E>java.util.concurrent.SynchronousQueue<E>

A blocking queue in which each insert operation must wait for a corresponding remove operation by another thread, and vice versa. A synchronous queue does not have any internal capacity, not even a capacity of one. You cannot peek at a synchronous queue because an element is only present when you try to remove it; you cannot insert an element (using any method) unless another thread is trying to remove it; you cannot iterate as there is nothing to iterate. The head of the queue is the element that the first queued inserting thread is trying to add to the queue; if there is no such queued thread then no element is available for removal and poll() will return null. For purposes of other Collection methods (for example contains), a SynchronousQueue acts as an empty collection. This queue does not permit null elements [https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/SynchronousQueue.html]

• boolean offer(E e)– Inserts the specified element into this queue, if another thread is waiting to receive it.

• void put(E o)– Adds the specified element to this queue, waiting if necessary for another thread to receive it.

• E poll()– Retrieves and removes the head of this queue, if another thread is currently making an

element available.

Curs 7 - PPD - 11

Page 12: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Exemplupublic class SynchronousQueueDemo{ public static void main(String args[]) { final SynchronousQueue<String> queue = new SynchronousQueue<String>();

Thread producer = new Thread("PRODUCER") { public void run() {

String event = "FOUR"; try { queue.put(event); // thread will block here

System.out.printf("[%s] published event : %s %n”, Thread .currentThread().getName(), event); }

catch (InterruptedException e) { e.printStackTrace(); } } };

producer.start(); // starting producer thread

Thread consumer = new Thread("CONSUMER") {public void run() {

try { String event = queue.take(); // thread will block here System.out.printf("[%s] consumed event : %s %n",

Thread .currentThread().getName(), event); } catch (InterruptedException e) { e.printStackTrace(); } }

}; consumer.start(); // starting consumer thread

} Curs 7 - PPD - 12

Page 13: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Sincronizare <-> comunicare

Programele comunică între ele nu numai pentru a-şi comunica informaţii sub formă de mesaje ci şi pentru a se sincroniza.=>Un semnal de sincronizare poate fi considerat şi el că este un mesaj fără conţinut ce se transmite între programe.

Cum se realizează acest lucru?

Curs 7 - PPD - 13

Page 14: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Procese secvenţiale comunicante. Rendez-vous simetric.

task-ul A: o comandă de emitere mesaj → SUSPENDARE ← task-ul B: o comandă de recepţie de mesaj;

task-ul B: o comandă de recepţie de mesaj → SUSPENDARE ← task-ul A:o comandă de emisie de mesaj;

task-uri sincronizate→ datele (mesajul) sunt transferate

Curs 7 - PPD - 14

Page 15: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Procese distribuite. Rendez-vous asimetric

• Comunicarea şi sincronizarea între programele concurente se realizează în acest caz similar cu apelarea prin nume de către programul emiţător a unei proceduri incluse în programul receptor, – lista cu parametrii asociaţi acestui apel fiind folosită ca un “canal” de

comunicare pentru transmiterea de date între cele două programe.

• Doar programul apelant trebuie să cunoască numele programului apelat, nu şi invers.

Curs 7 - PPD - 15

Page 16: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Operatii atomice

Curs 7 - PPD - 16

Page 17: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Operatii atomice

Curs 7 - PPD - 17

• Operaţii cu întregi: o incrementare, decrementare, adunare, scădereo compare-and-swap (CAS) operatii

CAS – instructiune atomica care compara continutul memoriei cu o valoare data si doar daca aceastea sunt egala modifica continutul locatieide memorie cu noua valoare data.

The value of CAS is that it is implemented in hardware and is extremely lightweight (on most processors).

Page 18: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Compare and swap (CAS)http://www.ibm.com/developerworks/library/j-jtp11234/

• The first processors that supported concurrency provided atomic test-and-set operations, which generally operated on a single bit.

• The most common approach taken by current processors, including Intel and Sparc processors, is to implement a primitive called compare-and-swap, or CAS.

• On Intel processors, compare-and-swap is implemented by the cmpxchgfamily of instructions.

• PowerPC processors have a pair of instructions called "load and reserve" and "store conditional" that accomplish the same goal; similar for MIPS, except the first is called "load linked.”

Curs 7 - PPD - 18

Page 19: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

CAS operation

• A CAS operation includes three operands– a memory location (V), – the expected old value (A), and– a new value (B).

• The processor will atomically update the location to the new value(V==B) if the value that is there matches the expected old value (V==A), otherwise it will do nothing.

• In either case, it returns the value that was at that location prior to the CAS instruction.

Curs 7 - PPD - 19

Page 20: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

CAS synchronization

• The natural way to use CAS for synchronization is to read a value A from an address V, perform a multistep computation to derive a new value B, and then use CAS to change the value of V from A to B. – The CAS succeeds if the value at V has not been changed in the

meantime.

• Instructions like CAS allow an algorithm to execute a read-modify-writesequence without fear of another thread modifying the variable in the meantime, because if another thread did modify the variable, the CAS would detect it (and fail) and the algorithm could retry the operation.

Curs 7 - PPD - 20

Page 21: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

JAVA

Curs 7 - PPD - 21

Page 22: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

22

Java volatile

• Volatile indica faptul ca valoare uneivariabila va fi modificata de catre maimulte threaduri.

• Informatii necesare pt JVM: -nu trebuie reordonate instructiunile

corespunzatoare• Valoarea nu va fi cached thread-locally:

Þ" reads & writes direct in "main memory";

http://tutorials.jenkov.com/images/java-concurrency/java-volatile-2.png

Curs 7 - PPD -

Page 23: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Curs 7 - PPD - 24

Difference between synchronized and volatile Characteristic Synchronized Volatile Type of variable Object Object or primitive Null allowed? No Yes Can block? Yes No All cached variables synchronized on access? Yes From Java 5 onwards

When synchronization happens

When you explicitly enter/exit a synchronized block

Whenever a volatile variable is accessed.

Can be used to combined several operations into an atomic operation?

Yes Pre-Java 5, no. Atomic get-set of volatiles possible in Java 5.

Page 24: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

25

Volatile

• If a variable is declared as volatile then is guaranteed that any thread which reads the field will see the most recently written value.

• From Java 5 changes to a volatile variable are always visible to other threads. What’s more it also means that when a thread reads a volatile variable in java, it sees not just the latest change to the volatile variable but also the side effects of the code that led up the change.

• As of Java 5 write access to a volatile variable will also update non-volatile variables which were modified by the same thread.

class VolatileExample {int x = 0;volatile boolean v = false;public void writer() {

x = 42;v = true;

}

public void reader() {if (v == true) {

//uses x - guaranteed to see 42.}

}}

Curs 7 - PPD -

Page 25: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

26

Exemplu

/*** In this example Singleton Instance is declared as volatile variable to ensure* every thread see updated value for _instance.* * @author Javin Paul*/

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;

}

Curs 7 - PPD -

Page 26: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

volatile nu e suficient – in anumite cazuri….

v

http://tutorials.jenkov.com/images/java-concurrency/java-volatile-3.png

Curs 7 - PPD - 27

volatile variable is not suitable for cases where we want to read-update-write as an atomic operation

• Volatile guarantees only Visibility. It does'nt guarantee atomicity.

• If We have two volatile writes in a method which is being accessed by a thread A and another thread B is accessing those volatile variables , then while thread A is executing the method it might be possible that thread A will be preempted by thread B in the middle of operations(e.g. after first volatile write but before second volatile write by the thread A).

Page 27: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Atomic types

Curs 7 - PPD - 29

Page 28: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

java.util.concurrent.atomic

Curs 7 - PPD - 30

A small toolkit of classes that support lock-free thread-safe programming on single variables.

Page 29: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Exemplu

class Sequencer {

private final AtomicLong sequenceNumber = new AtomicLong(0);

public long next() {return sequenceNumber.getAndIncrement();

}}

Curs 7 - PPD - 31

Page 30: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Operatii specifice

• get has the memory effects of reading a volatile variable.• set has the memory effects of writing (assigning) a volatile variable.• lazySet has the memory effects of writing (assigning) a volatile variable except

that it permits reorderings with subsequent (but not previous) memory actions that do not themselves impose reordering constraints with ordinary non-volatile writes. Among other usage contexts, lazySet may apply when nulling out, for the sake of garbage collection, a reference that is never accessed again.

• weakCompareAndSet atomically reads and conditionally writes a variable but does not create any happens-before orderings, so provides no guarantees with respect to previous or subsequent reads and writes of any variables other than the target of the weakCompareAndSet.

• compareAndSet and all other read-and-update operations such as getAndIncrement have the memory effects of both reading and writing volatile variables.

Curs 7 - PPD - 32

Page 31: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

AtomicIntegerjava.lang.Objectjava.lang.Numberjava.util.concurrent.atomic.AtomicInteger

Curs 7 - PPD - 33

Page 32: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Intructiuni atomice – C++11

Curs 7 - PPD - 34

Page 33: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

C++ Counter

#include <atomic>

struct AtomicCounter {std::atomic<int> value;

void increment(){++value;

}

void decrement(){--value;

}

int get(){return value.load();

}};

Curs 7 - PPD - 35

Page 34: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

template <class T> struct atomic;

AtomicObjects of atomic types contain a value of a particular type (T).

The main characteristic of atomic objects is that access to this contained value from different threads cannot cause data races.

Additionally atomic objects have the ability to synchronize access to other non-atomic objects in their threads by specifying different memory orders.

Template parametersT

Type of the contained value.This shall be a trivially copyable type.

Curs 7 - PPD - 36

Page 35: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

C-style atomic types

Curs 7 - PPD - 37

Page 36: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Functions for atomic objects (C-style)atomic_is_lock_freeIs lock-free (function )atomic_initInitialize atomic object (function )atomic_storeModify contained value (function )atomic_store_explicitModify contained value (explicit memory order) (function )atomic_loadRead contained value (function )atomic_load_explicitRead contained value (explicit memory order) (function )atomic_exchangeRead and modify contained value (function )atomic_exchange_explicitRead and modify contained value (explicit memory order) (function )atomic_compare_exchange_weakCompare and exchange contained value (weak) (function )atomic_compare_exchange_weak_explicitCompare and exchange contained value (weak, explicit) (function )atomic_compare_exchange_strongCompare and exchange contained value (strong) (function )atomic_compare_exchange_strong_explicit

Compare and exchange contained value (strong, explicit) (function )atomic_fetch_addAdd to contained value (function )atomic_fetch_add_explicitAdd to contained value (explicit memory order) (function )atomic_fetch_subSubtract from contained value (function )atomic_fetch_sub_explicitSubtract from contained value (explicit memory order) (function )atomic_fetch_andApply bitwise AND to contained value (function )atomic_fetch_and_explicitApply bitwise AND to contained value (explicit memory order) (function )atomic_fetch_orApply bitwise OR to contained value (function )atomic_fetch_or_explicitApply bitwise OR to contained value (explicit memory order) (function )atomic_fetch_xorApply bitwise XOR to contained value (function )atomic_fetch_xor_explicitApply bitwise XOR to contained value (explicit memory order) (function )

Curs 7 - PPD - 38

Page 37: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Intreruperi threaduri

Curs 7 - PPD - 39

Page 38: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Intreruperi

• O intrerupere ( interrupt ) este o indicatie pentru un thread ca ar trebui sase opreasca si … sa faca altceva (de ex. sa se termine).

public void interrupt()

public static boolean interrupted()

public boolean isInterrupted()

“There is no way in Java to terminate a thread unless the thread exits by itself.”

Curs 7 - PPD - 40

Page 39: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

41

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, <interrupt status> este sters.

• Metoda nestatica isInterrupted, care este folosita de catre un thread pt a verificastatusul (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.

Curs 7 - PPD -

Page 40: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

42

Exemplupublic 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[] = {”Studentii sunt prezenti.",”Examenul este greu.",“Vacanta este asteptata.",”Exista concurenta."

};try {

for (int i = 0; i < importantInfo.length; i++) {// Pause for 4 secondsThread.sleep(4000);// Print a messagethreadMessage(importantInfo[i]);

}} catch (InterruptedException e) {

threadMessage("I wasn't done!");}

}} Curs 7 - PPD -

Page 41: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

43

public static void main(String args[])throws InterruptedException {

// Delay, in milliseconds before// we interrupt MessageLoop// thread (default one hour).

long patience = 1000 * 60 * 60;

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!");

}}

Curs 7 - PPD -

Page 42: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

44

Interactiuni: Waits, Notification,Interruption

• Notificarile nu se pot pierde din cauza intreruperilor.

• Presupunem ca un set de threaduri s este in wait set a lui m, si alt thread executa notificarepe m.

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 atunci un alt thread din wait set va fi notificat.

• Daca thread t a fost sters din wait set a lui m din cauza unei intreruperi atunci interruption status al lui t este setat la false si se iese din wait cu aruncarea unei exceptii de tipInterruptedException.

Curs 7 - PPD -

Page 43: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

45

Conditionare - reguli

• folosirea operatiilor wait doar in cicluri care se termina atunci cand anumiteconditii logice sunt indeplinite!

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

De exemplu: daca t este in wait set al obiectului o, atunci cand apare atat o intrerupere a lui t cat si o notificare a lui o, trebuie sa existe o ordine intre acesteevenimente. ÷ 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 priminotificarea.

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

Curs 7 - PPD -

Page 44: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

46

Un thread t poate fi sters din wait set al unui obiect 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” (no apparent reason) –/rare.(https://en.wikipedia.org/wiki/Spurious_wakeup)

Concluzii

Curs 7 - PPD -

Page 45: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Nested monitor lockout

• Thread 1 blocheaza A– Thread 1 blocheaza B (in timp se ramane blocajul pe A)

• Thread 1 decide sa astepte un semnal de la un alt thread• Thread 1 apeleaza B.wait() => elibereaza B dar nu si pe A.

• Thread 2 trebuie sa blocheze atat pe A cat si pe B (in ordine) pentru a trimite un semnal catre Thread 1.

• Thread 2 nu poate bloca pe A (pt ca Thread 1 are blocajul lui A).• Thread 2 ramane blocat indefinit asteptand ca A sa fie eliberat.

• Thread 1 ramane blocat indefinit asteptand un semnal de la Thread 2, siastfel nu elibereaza pe A, etc.

Curs 7 - PPD - 47

Page 46: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Diferenta intre Deadlock si Nested monitor lockout

• In cazul deadlock, 2 (sau mai multe) threaduri se asteapta unul pe altul saelibereze blocajul.

• In cazul nested monitor lockout:– Thread 1 blocheaza A, si asteapta un semnal de la Thread 2. – Thread 2 asteapta sa-l blocheze pe A pentru a trimite semnalul catre

Thread 1.

Curs 7 - PPD - 48

Page 47: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Exemplu – intrerupere thread

Thread loop = new Thread(new Runnable() {

public void run() {while (true) {

if (Thread.interrupted()) { break; }// Continue to do what it should be done

}}

});…loop.start();loop.interrupt();

Curs 7 - PPD - 49

Page 48: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

ThreadLocal

• Variabile locale fiecarui thread (pt fiecare thread se creeaza o copie)• Instantele sunt in general campuri private static in clase care doresc sa asocieze cate o stare fiecarui thread• Trei metode publice : set, get, remove

private ThreadLocal<String> myThreadLocal = new ThreadLocal<String>();

myThreadLocal.set("Hello ThreadLocal");

String threadLocalValue = myThreadLocal.get();

• Valorile obiectului de tip ThreadLocal sunt vizibile doar de catre thread-ul care seteaza valoarea.

• Setare valoare initiala:

private ThreadLocal myThreadLocal = new ThreadLocal<String>() {@Override protected String initialValue() {

return "This is the initial value";}

};

Curs 7 - PPD - 50

Page 49: Curs 7 - Babeș-Bolyai Universityvniculescu/didactic/PPD/C7.pdfCurs 7 -PPD - 26 Exemplu /** * In this example Singleton Instance is declared as volatile variable to ensure * every

Exemplul – Atomic + ThreadLocal

import java.util.concurrent.atomic.AtomicInteger;

public class ThreadId {// Atomic integer containing the next thread ID to be assignedprivate static final AtomicInteger nextId = new AtomicInteger(0);

// Thread local variable private static final ThreadLocal<Integer> threadId = new ThreadLocal<Integer> () {

@Override protected Integer initialValue() {

return nextId.getAndIncrement();}

};

// Returns the current thread's unique ID, assigning it if necessarypublic static int get() {

return threadId.get();}

}

Curs 7 - PPD - 51