Upload
gwen-rogers
View
214
Download
0
Embed Size (px)
Citation preview
Critical Reference
• An occurrence of a variable v is defined to be critical reference:
a. if it is assigned to in one process and has an occurrence in another process.
b. if it has an occurrence in an expression in one process and is assigned to in another.
Limited Critical Reference
• A program satisfies the limited-critical-reference (LCR) restriction if each statement contains at most one critical reference
• Consider the first occurrence of n in nn+1. It is assigned to in process p and has (two) occurrences in process q, so it is critical by (a).
• The second occurrence of n in nn+1 is critical by (b) because it appears in the expression n n+1 in p and is also assigned to in q.
• Consider now the version of the statements that uses local variables. Again, the occurrences of n are critical, but the occurrences of temp are not.
• Therefore, the program satisfies the LCR restriction.
LCR program
LCR
• Concurrent programs that satisfy the LCR restriction yield the same set of behaviors whether the statements are considered atomic or are compiled to a machine architecture with atomic load and store.
Volatile and Non-Atomic Variables
• Volatile variables
• The single statement in process q can be interleaved at any place during the execution of the statements of p.
• Because of optimization during compilation, the computation in q may not use the most recent value of n.
• The value of n may be maintained in a register from the assignment in p1 through the computations in p2, p3 and p4, and only actually stored back into n at statement p5.
• Furthermore, the compiler may re-order p3 and 4 to take advantage of the fact that the value of n+5 needed in p3 is computed in p4.
• These optimizations have no semantic effect on sequential programs, but they do in concurrent programs that use global variables, so they can cause programs to be incorrect.
• Specifying a variable as volatile instructs the compiler to load and store the value of the variable at each use, rather than attempt to optimize away these loads and stores.
• Concurrency may also affect computations with multiword variables.
• A load or store of a full-word variable (32 bits on most computers) is accomplished atomically, but if you need to load or store longer variables (like higher precision numbers), the operation might be carried out non-atomically.
• A load from another process might be interleaved between storing the lower half and the upper half of a 64-bit variable.
• If the processor is not able to ensure atomicity for multiword variables, it can be implemented using a synchronization mechanism such as those to be discussed throughout the book.
• However, these mechanisms can block processes, which may not be acceptable in a real-time system.
Concurrency Programs
• the normal execution of a program on a computer is not the best way to study concurrency.
• Later in this section, we discuss the implementation of concurrency, because eventually you will wish to write concurrent programs using the constructs available in real languages, but for studying concurrency there is a better way.
Concurrent Counting Algorithm
The algorithm simply increments a global variable twenty times, ten times in each of two processes.
Java Threads
CS 556 – Distributed Systems
Tutorial on Java Threads
Java Threads
Threads
• A thread is a lightweight process – a single
sequential flow of execution within a program
• Threads make possible the implementation of programs that seem to perform multiple tasks at the same time (e.g. multi-threaded Web servers)
• A new way to think about programming
Java Threads
Java Threads
We will cover:• How to create threads in Java
Java Threads
How to create Java Threads
There are two ways to create a Java thread:
1. Extend the java.lang.Thread class
2. Implement the java.lang.Runnable interface
Java Threads
Extending the Thread class
• In order to create a new thread we may subclass java.lang.Thread and customize what the
thread does by overriding its empty run method.
• The run method is where the action of the thread
takes place.
• The execution of a thread starts by calling the start method.
Java Threads
Example Iclass MyThread extends Thread { private String name, msg;
public MyThread(String name, String msg) { this.name = name; this.msg = msg; } public void run() { System.out.println(name + " starts its execution"); for (int i = 0; i < 5; i++) { System.out.println(name + " says: " + msg); try { Thread.sleep(5000); } catch (InterruptedException ie) {} } System.out.println(name + " finished execution"); }}
Java Threads
Example Iclass MyThread extends Thread { private String name, msg;
public MyThread(String name, String msg) { this.name = name; this.msg = msg; } public void run() { System.out.println(name + " starts its execution"); for (int i = 0; i < 5; i++) { System.out.println(name + " says: " + msg); try { Thread.sleep(5000); } catch (InterruptedException ie) {} } System.out.println(name + " finished execution"); }}
Java Threads
Example Iclass MyThread extends Thread { private String name, msg;
public MyThread(String name, String msg) { this.name = name; this.msg = msg; } public void run() { System.out.println(name + " starts its execution"); for (int i = 0; i < 5; i++) { System.out.println(name + " says: " + msg); try { Thread.sleep(5000); } catch (InterruptedException ie) {} } System.out.println(name + " finished execution"); }}
Java Threads
Example I (cont.)
public class test { public static void main(String[] args) { MyThread mt1 = new MyThread("thread1", "ping"); MyThread mt2 = new MyThread("thread2", "pong"); mt1.start(); mt2.start(); }}
the threads will run in parallel
Java Threads
Example I (cont.)
• Typical output of the previous example:
thread1 starts its executionthread1 says: pingthread2 starts its executionthread2 says: pongthread1 says: pingthread2 says: pongthread1 says: pingthread2 says: pongthread1 says: pingthread2 says: pongthread1 says: pingthread2 says: pongthread1 finished executionthread2 finished execution
Java Threads
Implementing the Runnable interface
• In order to create a new thread we may also provide a class that implements the java.lang.Runnable interface
• Preffered way in case our class has to subclass some other class
• A Runnable object can be wrapped up into a Thread object– Thread(Runnable target)– Thread(Runnable target, String name)
• The thread’s logic is included inside the run method of the runnable object
Java Threads
Example II
class MyClass implements Runnable { private String name; private A sharedObj; public MyClass(String name, A sharedObj) { this.name = name; this.sharedObj = sharedObj; } public void run() { System.out.println(name + " starts execution"); for (int i = 0; i < 5; i++) { System.out.println(name + " says: " + sharedObj.getValue()); try { Thread.sleep(5000); } catch (InterruptedException ie) {} } System.out.println(name + " finished execution"); }}
Java Threads
Example II (cont.)
class A { private String value; public A(String value) { this.value = value; } public String getValue() { return value; }}
public class test2 { public static void main(String[] args) { A sharedObj = new A("some value"); Thread mt1 = new Thread(new MyClass("thread1", sharedObj)); Thread mt2 = new Thread(new MyClass("thread2", sharedObj)); mt1.start(); mt2.start(); }}
shared variable
Java Threads
Example II (cont.)• Typical output of the previous example:
thread1 starts executionthread1 says: some valuethread2 starts executionthread2 says: some valuethread1 says: some valuethread2 says: some valuethread1 says: some valuethread2 says: some valuethread1 says: some valuethread2 says: some valuethread1 says: some valuethread2 says: some valuethread1 finished executionthread2 finished execution
start() && join()
Java•Concurrency is built in to the language.– p.start() puts thread p in the ready (Enabled)
queue.– p.join(), executed by main, suspends main until
thread p terminates.
throws
• If a method is capable of causing an exception that it does not handle, it must specify this behavior so that callers of the method can guard themselves against that exception.
• You do this by including a throws clause in the method’s declaration.
The throw statement
• throw expression ;• The type of expression must be a subtype of
class Throwable.• The enclosing block statement terminates
abruptly. The thrown exception may be caught by a try-catch statement.
Class hierarchy (partial)
• Throwable• Error
– OutOfMemoryError– Exception– IOException– RuntimeException– ArithmeticException– IndexOutOfBoundsException– ArrayIndexOutOfBoundsException– StringIndexOutOfBoundsException– NegativeArraySizeException
The try-catch-finally statement
trybody
catch(E1 x1)catchBody1
catch(E2 x2)catchBody2
...finally
finallyBody
try-catch with no finally
Concurrent Counting Algorithm
import java.lang.String;import java.lang.Thread;
class Count extends Thread {
//fieldstatic volatile int n;
//constructorvoid Count(){}
//methodpublic void run(){}public static void main(String[] s0){}
}
class Count extends Thread { static volatile int n = 0;
public void run() { int temp; for (int i = 0; i < 10; i++) { temp = n; n = temp + 1; } }
public static void main(String[] args) { Count p = new Count(); Count q = new Count(); p.start(); q.start(); try { p.join(); q.join(); } catch (InterruptedException e) { } System.out.println("The value of n is " + n); }}