Codes counter with print counter with yield counter with timeout counter with problem counter with...

56
Codes • counter with print • counter with yield • counter with timeout • counter with problem • counter with yield at bad place • counter with sync • counter with semaphore

Transcript of Codes counter with print counter with yield counter with timeout counter with problem counter with...

Page 1: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Codes

• counter with print• counter with yield• counter with timeout• counter with problem• counter with yield at bad place• counter with sync• counter with semaphore

Page 2: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Distributed Systems3. Java Threads

Simon Razniewski

Faculty of Computer ScienceFree University of Bozen-Bolzano

A.Y. 2014/2015

Page 3: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Why processes and threads

• Several processes– Skype– Browser– Music player

• Several actions within a process– send and receive at the same time– reaction to user input while doing expensive steps

(e.g. network communications, calculations, disk fetching)

Page 4: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Process

•What is a process?• The unit of computation inside an Operating System• A running program with its data and resources– Code (text) of the program– Data: global variables– Program Counter– CPU registers– Stack: parameters, local variables– Resources: open files, network connections, I/O, …

• JVM runs as a single process

Page 5: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Process

•What is a process?• The unit of computation inside an Operating System• A running program with its data and resources– Code (text) of the program– Data: global variables– Program Counter– CPU registers– Stack: parameters, local variables– Resources: open files, network connections, I/O, …

• JVM runs as a single process

Page 6: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Process States

init

ready running

blocked

terminated

creation

event wait for event

assign CPU

revoke CPU

termination

Active process

• Multitasking system multiple running processes• Single processor one active process

– Time sharing, context switch

Page 7: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Thread

• Lightweight process: smallest unit of computation that can be scheduled in an O.S.

• Shares code and data with other associated threads– Task: set of threads that refer to the same code and data– Process = task with (at least) a single thread!

• Task taken as synonym of process

• It is a single control-flow within a process• Multithreading like Multitasking• Execution of Java program: JVM creates a thread that

executes the main method– Other threads can be dynamically created

Page 8: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Thread: Features

• Memory sharing: threads share variables– No reserved memory for data and heap: all

threads in a process share the same address space• Private stack and program counter• Low context switch cost– No need to handle code&data– Much more performing than for processes

• But… privacy/synchronization issues: threads of the same task can modify each other’s data

Page 9: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Single vs Multithreaded Processes

Page 10: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Java Thread: Big PictureProcess

Code

Static variables

Memory

Thread 1Stack 1

local var., methods

PC 1

Thread 2Stack 2

local var., methods

PC 2

Thread 3Stack 3

local var., methods

PC 3

Page 11: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Implementation

• java.lang.Thread class• Provides the functionalities for a thread• With new(), the thread is created but is still

not active• start() activates the thread• start() calls run(), empty method– Extend Thread and override run() in order to

implement a thread!

Page 12: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Simple Skeletonclass SimpleThread extends Thread {

public void SimpleThread() { <constructor> }

public void run() { <behavior of each instance of SimpleThread>

}}

public class SimpleMain{

public static void main (string[] args){

Thread t1=new SimpleThread();t1.start(); //Thread t1 activated … don’t call run()

directly!… //HOW MANY THREADS HERE?

}}

Page 13: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

A Thread not Thread

• Is it possible to define a JAVA thread that does not extend Thread?– JAVA does not support multiple inheritance

• Interface Runnable: a class denoting instances that can be run by a thread

• How-to– Implement Runnable and its run() method– Create a new object of this class– Create a new Thread passing the object as parameter of the

constructor– start() thread

Page 14: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Simple Skeletonclass SimpleRunnable extends MyClass

implements Runnable {

public void run() {<behavior here…>

}}

public class AnotherSimpleMain {public static void main(String args[]){

SimpleRunnable r = new SimpleRunnable();Thread t = new Thread(r);t.start();

}}

Page 15: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Thread Lifecycle

• New Thread– Thread created with new– Still inactive

• Runnable = executable (could be in execution)• Not runnable

– Cannot be currently scheduled for the execution• Dead

– Thread has autonomously finished its execution (end of run())– stop() method invoked on it

Page 16: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Not Runnable – Why?

• Waiting for I/O operation to terminate• Trying to access to synchronized

object/monitor queued• One of these methods has been invoked on it– sleep()– wait()– suspend()• Deprecated because prone to deadlock

• We will discuss these cases in detail…

Page 17: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Stopping a Thread

• Idea: stop the execution of a thread• stop() is deprecated because unsafe– We will see the notion of (un)locking– Basically, stop() causes the thread to

immediately release all resources (unexpectedly)– Objects protected by the lock could be in an

inconsistent state, and now accessed by other threads

• In general, google “Java Thread Primitive Deprecation”

Page 18: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

How to Stop a Thread

• Using a recurring pattern (we will re-use it later on)

private Thread myself;

public void stop() { //user-defined! myself = null; }

public void run() { Thread thisThread = Thread.currentThread(); while (myself == thisThread) {

<behavior here…> //RECHECK CONDITION IF THE CODE IS LARGE

} }

Page 19: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

A Shared Counter

• ParallelCounter– increment() increments the counter– decrement() decrements the counter

• CountingThread– Parameters:• String name• Int times

– Execution: increments or decrements the counter for times times

Page 20: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

What Happens?

Incrementor i1 = new Incrementor("A",5000000);Incrementor i2 = new Incrementor("B",5000000);i1.start();i2.start();while (!i1.hasFinished || !i2.hasFinished) {}System.out.println(counter);

What is the final value of the counter (when both i1 and i2 have finished)?

Page 21: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Counter

static void increment() {counter++;

}

cur countercounter cur + 1

Byte code

Page 22: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Counter

static void increment() {counter++;

}

cur countercounter cur + 1

Byte code

What if we have a context switch here?

Remember: value is shared, cur is local

Page 23: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Counter

static void increment() {int curVal = counter;Thread.yield();counter = curVal+1;

}

=> Eclipse

Page 24: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

The Problem

• Threads share the same address space• Common resources: objects can be manipulated by

multiple threads at the same time• Interference we need synchronization• Access control mechanisms: to define who and when

can correctly access to a resource– No deadlock: situation in which every thread is stuck– No livelock: situation in which threads continuously

execute without terminating– No starvation: we must guarantee that all threads can have

the possibility of accessing the resource sooner or later

Page 25: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Mutual Exclusion

• Operations on a shared objects by different threads cannot overlap in time

• No ordering constraint• Critical section: instructions that deal with the

object change• Critical sections of the same class cannot

overlap• At most one critical section of a class can be

executed at a given time

Page 26: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Solutions

• Ad-hoc algorithms with turn/busy variables– Difficult to generalize– Waiting for a resource reduces to an active cycle

(busy waiting)• Waste of resources

– Starvation?

Page 27: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Semaphores (Dijkstra)

• Non-negative integers indicating number of parallel accesses allowed

• manipulated through atomic operations: signal (V) incrementwait (P) decrement

• Read semaphore: when value=0, wait causes the thread to wait until the value becomes positive– Passive wait inside a queue– FCFS strategy to avoid starvation

• Binary semaphores: mutex

Page 28: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Mutual Exclusion with Semaphores

Thread 1

…s.wait();<critical section>s.signal();…

Thread 2

…s.wait();<critical section>s.signal();…

Semaphore s = new Semaphore(1);

N.B.: THIS IS NOT JAVA CODE

• This kind of semaphore is a lock

Page 29: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Limits of Semaphores

• Low-level programming construct• Easy to introduce errors: deadlock/livelock– Debugging concurrent programs is extremely

difficult• Examples in the mutex case– Inverting wait and signal makes it possible to

multiple access to the critical section– Using wait twice causes a deadlock

Monitor for Objects (Hoare)

Page 30: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Monitor (Abstract Model)

• Protects the data of a shared structure/resource– Data (state of the monitor) are persistent and

cannot be accessed directly• Object’s data attributes

– Public/Entry methods: unique entry point that can modify the state

Page 31: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Monitor Protection Levels• Level 1: mutual exclusion– Public methods are always mutually exclusive: at most one

thread can be active inside the monitor (lock)– If another thread tries to access one of the public methods

waits into an entry queue– Automatically enforced at the language level

• Level 2: regulates the order in which threads can access the resource– When an entry operation is called, it first checks a

synchronization condition (that induces an ordering)– Condition not met thread waits, monitor is freed – Suspension managed by the programmer through a condition

variable

Page 32: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Condition

• Special variable typecondition cond;

• Represents a queue containing waiting threads

• Monitor’s operations manipulate conditions through two operations– wait(cond) – signal(cond)

Page 33: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Signal and Wait

• Effect of wait(cond) – Thread is suspended and inserted into cond’s

queue– Monitor is freed– The thread will restart the execution after wait(cond), guaranteeing mutual exclusion

• Effect of signal(cond) – Reactivates one thread waiting in cond’s queue– Has no effect if cond’s queue is empty

Page 34: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Monitor QueuesMonitor

Entry queue

. . .

Condition queue (C1)

Condition queue (C2)

Condition queue (Cn)

active thread

Page 35: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Signal Semantics

• Execution of signal operation– Signaling thread Q (executes signal(cond))– Signaled thread P (extracted from cond’s queue)

• Both Q and P could execute… who has priority?– Signal and wait: Q halts and P continues• Blocking condition variables (Hoare’s monitor)

– Signal and continue: Q continues, P is notified and waits• Nonblocking condition variables (Mesa style monitor)

Page 36: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Signal Semantics: Schema

monitorfree?

entry queue

condition queue

in execution

Call

NO

YES

cond.wait()

monitor free

cond.signal_and_wait()

cond.signal_and_continue()

cond.signal_and_wait()

cond.signal_and_continue()

Page 37: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Signal and Wait

• Signaling thread: Q, signaled thread: P• Q is inserted into the entry queue– Or a second signal queue with higher

priority than the entry queue

• P is activated and occupies the monitor– No other process can

change the condition– Hence P can continue the

execution of the method– P restarts after thecond.wait()instructionthat blocked it

Page 38: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Signal and Continue (Java)

• Signaling thread: Q, signaled thread: P• Q continues (monitor still locked)• P is moved from cond’s queue

to the entry queue– Other processes can enter the

monitor between Q and PFirst instruction to be executed by P when it will be selected: re-test the synch. condition!

– Pattern:while(!synch_cond)

cond.wait();<access to resource>

Page 39: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Example: Bounded Mailbox

• Shared mailbox with capacity N• Monitor: circular message buffer (of size N)• Two entry operations to be executed in isolation

– void send(Message m) Cannot be accomplished if the buffer is full

– Message receive()Cannot be accomplished if the buffer is empty

Producer Thread

Consumer Thread

Page 40: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

monitor circular_buffer{

messagge buffer[N];int occupied=0; int head=0; int bottom=0;condition not_full;condition not_empty;

public void receive(messagge m){ /*proc. entry -> mutually exclusive */

if (occupied==N) not_full.wait;buffer[code]=m;head=(head + 1)%N;occupied++;not_empty.signal;

}

public messagge send(){ /*proc. entry -> mutually exclusive */ messagge m;

if (occupied == 0) not_empty.wait; m=buffer[head];

bottom=(bottom + 1)%N; occupied--;

not_full.signal;return m;

}}

Page 41: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Synchronization in Java

• Global environment (shared data): threads interact/interfere by operating on shared objects– Competition: synchronized methods, locks– Cooperation: semaphores and wait-notify,

conditions• Package java.util.concurrent

Page 42: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Basic Monitor in Java

• JVM associates a lock to every object– States whether the object is free/occupied– Entry set queue for suspended threads

• Critical sections can be identified with the keyword synchronized– Synchronized methods– Synchronized sections in the code

Page 43: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Synchronized Section

• Compiler manages a synchronized section– Adding a prologue for acquiring the object’s lock• Lock free thread can execute the critical section• Lock busy thread suspended into the entry set queue

of the object

– Adding an epilogue for releasing the lock• No suspended thread lock released• Else lock maintained and assigned to one of the

suspended threads

Page 44: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Synchronized Block

synchronized(obj) { <code> }• <code> is a critical section for object obj• Mutual exclusion is guaranteed for obj w.r.t.– Other executions of the same block– Other synchronized blocks for the same object

<Object mutexLock = …>…public void M( ) {

<non-critical section>;synchronized (mutexlock){<critical section>;}<non-critical section>;

}

Page 45: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

static synchronized void increment() {counter++;

}

• Synchronization is related to this (Counter object)• Mutual exclusion ensured for all synchronized methods

– E.g. also dec() method for Counter

Thread-Safe Counter

<lock acquisition or suspension>cur countercounter cur + 1<lock release or reassignment>

Byte code

Page 46: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Wait Set

• In addition to the entry set, each object is associated to another queue: wait set

• Special methods– wait(): insertion in the wait set– notify()/ notifyAll(): extraction from the

wait set– Can be invoked only by the thread owning the

object’s lock• Can be used only in a synchronized section

Page 47: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Wait and Notify(All)

• wait(): calling thread– Releases the lock – Is suspended in the wait set queue– N.B.: method throws InterruptedException

• notify(): one thread is selected from the wait set and moved into the entry set

• notifyAll(): all threads in the wait set are moved into the entry set

Policy: signal and continue!

Page 48: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Example: Bounded Mailbox• void send(Message m)

– Synchronized– Cyclic test (mailbox full wait())– After message insertion notify all

• Message receive()– Synchronized– Cyclic test (mailbox empty wait())– After message extraction notify all

• Is this efficient?

Producer Thread

Consumer Thread

Page 49: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Limitations of the Basic Monitor

• One queue for mutual exclusion (entry set)

• Only one queue for synchronizing threads on an object (wait set)

Conditions and Semaphors (from Java 5)

Page 50: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Java Semaphores

• Java (from 5.0) also explicitly supports semaphores (java.util.concurrent.Semaphore)

• Constructor: takes– Permits (no.): number of permits initially granted– Fairness (yes/no): if true, suspended threads will acquire

the resource in the order they asked for it• Basic methods– acquire() wait– release() signal

• Other useful methods (see JavaDoc)

Page 51: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Example: Bounded Mailbox

• How to realize it without a monitor, but only semaphores?

• How many semaphores?• How are they initialized?

Producer Thread

Consumer Thread

Page 52: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Other Useful Methods• sleep(long ms)

– Suspends thread for the specified amount of time• interrupt()

– Triggers an event that causes the interruption of thread• interrupted() isInterrupted()

– Check whether the current thread has been interrupted• join()

– Waits for the termination of the specified thread• isAlive()

– true if thread has been started and has not yet terminated its execution• yield()

– Forces thread to release CPU• Other useful methods: JavaDoc of Thread class

– E.g. Thread.getCurrentThread() returns the currently active thread

Page 53: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

On Deprecated Methods• stop() forces thread termination

– All resources (e.g. locks) are instantaneously freed– If the thread was doing an “atomic” operation, the object’s state could

be left in an inconsistent state– The object can be now accessed by other threadShould not be used

• suspend() blocks a thread until resume() is invoked– Resources are not freed (e.g. locks are maintained)– If the thread has acquired a mutually exclusive resource (monitor), the

resource is blockedShould not be used

• In general, follow the “Java Thread Primitive Deprecation” guide (part of Java SE Documentation)

Page 54: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Thread-safe Datastructures

• Common data structures not thread-safe• LinkedList

• BlockingQueue• ConcurrentMap• CopyOnWriteArrayList

Page 55: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

On Priorities

• Threads have two methods for priorities– setPriority(int v)

v [MIN_PRIORITY, MAX_PRIORITY]∈– getPriority()

• Java suggested best practice:– Among runnable threads, choose the ones of higher priority– Round robin over threads of the same priority– Interrupt thread if a thread of higher priority is runnable

• Some JVM implementations: delegate threads’ scheduling to O.S. behavior depends on JVM + OS

Use with care

Page 56: Codes counter with print counter with yield counter with timeout counter with problem counter with yield at bad place counter with sync counter with semaphore.

Summary

• Java threads:– extend Thread– implement Runnable

• Synchronization an issue– Java provides techniques

• synchronized classes/methods/code snippets• semaphores• Synchronized data structures