Practical Session 6 Multitasking vs multithreading Threads Concurrency

  • Slides: 25
Download presentation
Practical Session 6 • • • Multitasking vs. multithreading Threads Concurrency vs. Parallelism Java

Practical Session 6 • • • Multitasking vs. multithreading Threads Concurrency vs. Parallelism Java Threads Thread confinement Object/Class Immutability

Multitasking vs. Multithreading • Multitasking: – Running more than one process on same processor.

Multitasking vs. Multithreading • Multitasking: – Running more than one process on same processor. – Uses context switching between different processes: (context=CPU state=content of CPU registers + program counter) • Switching from process A to B: – Context of process A is stored. – Context of process B is restored. • Multithreading: – Running more than one thread under same process. – Has the ability of resource sharing – all threads can access all resources of a process.

Threads • Definition – A way to share a single CPU between multiple tasks.

Threads • Definition – A way to share a single CPU between multiple tasks. • Benefits – Allows maintaining responsiveness of an application. • HTTP Server waiting for requests – Enable cancellation of separate tasks – Some problems require parallelism • Google’s Map/Reduce – Allows monitoring status of a resource (data base) – Allows taking advantage of multiple processors

Concurrency vs. Parallelism • Concurrency: – Two tasks can start and compete for CPU

Concurrency vs. Parallelism • Concurrency: – Two tasks can start and compete for CPU resources • Two threads running on same processor • They “share” the processor. • Parallelism – Two tasks that run at the same time in parallel. • They do not compete on process time. • Threads are executing simultaneously

Concurrency vs. Parallelism CPU Copyright © 2002, De. Lorme CPU 1 CPU 2

Concurrency vs. Parallelism CPU Copyright © 2002, De. Lorme CPU 1 CPU 2

Java Threads • Done by implementing the interface java. lang. Runnable. • java. lang.

Java Threads • Done by implementing the interface java. lang. Runnable. • java. lang. Runnable – Allows any class that implements it to operate as a thread. – Requires one method to be implemented: • public void run() – Implementation: class <class. Name> implements Runnable { public void run(){ //the “main” function of the thread } }

How to Run Threads • By implementing Runnable and wrapping it with a Thread

How to Run Threads • By implementing Runnable and wrapping it with a Thread instance. – takes a single Runnable object and executes it in a separate thread. – It is activated by calling start() • calls the Runnable run() method. • By implementing Runnable and passing it to an Executor. • By extending the Thread class.

Wrapped by a Thread- Threads 01. java class Simple. Runnable implements Runnable { private

Wrapped by a Thread- Threads 01. java class Simple. Runnable implements Runnable { private String name; } Simple. Runnable(String name) { this. name = name; } //prints name three time waits 0. 1 second between each print public void run() { for (int i = 0; i < 3; i++) { System. out. println("RUNNABLE: " + this. name); try { Thread. sleep(100); //time in miliseconds } catch (Exception e) { e. print. Stack. Trace(); } } }

public class Threads 01 { //creates to sime. Runnable threads and starts them public

public class Threads 01 { //creates to sime. Runnable threads and starts them public static void main(String[] a) { Simple. Runnable r 1 = new Simple. Runnable("r 1"); Thread t 1 = new Thread(r 1); Simple. Runnable r 2 = new Simple. Runnable("r 2"); Thread t 2 = new Thread(r 2); } } t 1. start(); t 2. start(); The order of start does not guarantee the order of execution.

Runnable Executor • Used to run threads that implemented Runnable • Decouples task creating

Runnable Executor • Used to run threads that implemented Runnable • Decouples task creating and task running: – Class does not have to be ran right after creation • Creating the Executor: • Executor. Service e = Executors. new. Fixed. Thread. Pool(<number. Of. Threads>); – number. Of. Threads: maximal number of threads running at same time. • Executing the thread: – e. execute(Runnable object); • Shutting down executor: – e. shutdown() • Causes the executor not to accept any new threads, and close all threads when all submitted tasks are done.

Using Executor - Threads 01 e. java class Simple. Runnable implements Runnable { private

Using Executor - Threads 01 e. java class Simple. Runnable implements Runnable { private int m_number; public Simple. Runnable(int i) { this. m_number = i; } } /** * Main lifecycle of the task. * Prints the task ID 10 times. */ public void run() { for (int i = 0; i < 10; i++) { System. out. print(" " + m_number); } }

import java. util. concurrent. *; public class Threads 01 e { public static void

import java. util. concurrent. *; public class Threads 01 e { public static void main(String[] a) { // Create an executor: Executor. Service e = Executors. new. Fixed. Thread. Pool(3); } } // create 10 runnables, and execute them. for(int i=0; i<10; i++) { System. out. println("creating a new task: " + i + " "); Simple. Runnable r = new Simple. Runnable(i); e. execute(r); } e. shutdown();

Extending Java Threads • Java. lang. Thread – Allows maximal threading functionality – Less

Extending Java Threads • Java. lang. Thread – Allows maximal threading functionality – Less common than Runnable, however much more powerful. – Requires one method to be implemented: • public void run() • Implementation: class <classname> extends Thread{ public void run(){ //thread “main” function } }

Threads can be Dangerous • Having things run "at the same time, in the

Threads can be Dangerous • Having things run "at the same time, in the same place", can be dangerous. • The two tasks can interfere with each other, and unexpected results might occur.

Example – shared counter public class Counter{ private int f. Counter; public Counter(){ f.

Example – shared counter public class Counter{ private int f. Counter; public Counter(){ f. Counter = 0; } public void increment(){ f. Counter++; } } public int get. Value(){ return f. Counter; }

public class Incrementer implements Runnable { Counter f. Counter; Incrementer(Counter ctr) { f. Counter

public class Incrementer implements Runnable { Counter f. Counter; Incrementer(Counter ctr) { f. Counter = ctr; } } /** * Main lifecycle. * increment the counter 200 times then dies. */ public void run() { for (int i = 0; i<200; i++) { f. Counter. increment(); } }

public class Threads 03{ // Demonstrating problems with access to a shared resource. public

public class Threads 03{ // Demonstrating problems with access to a shared resource. public static void main(String[] a) { for (int i=1; i<10; i++){ // create our shared object Counter ctr = new Counter(); Thread t 1 = new Thread(new Incrementer(ctr)); Thread t 2 = new Thread(new Incrementer(ctr)); } } } t 1. start(); t 2. start(); //wait until their job is done while (t 1. is. Alive() || t 2. is. Alive()); //wait until all done. //print out result of attempt i System. out. println("Attempt " + i + ", total value: " + ctr. get. Value()); }

Shared Resources and Safety • Safety problems arise when multiple threads access the same

Shared Resources and Safety • Safety problems arise when multiple threads access the same resource. • A shared resource is any object that is visible to several threads: – global (static) objects – non-primitive method parameters – class members. – Basically non-primitive variables.

class Foo { public static double NUMBER = 33. 3; } class Class. A

class Foo { public static double NUMBER = 33. 3; } class Class. A { public long i; public Vector v; class Task. A implements Runnable { //. . . private Class. A a; private List lst; public long r; public void run() { this. r = 2; Not safe - Accessing a public member variable. public Class. A() { /*. . . */ } this. a. do. Something(9, lst); Not Safe - The private member public void do. Something(long x, List lst) { } variable (lst) is exposed to class A. long local. Var = 0; } Object o; class Main { Not safe - Accessing a public o = this. v. element. At(2); member variable. public static void main(String[] args) { local. Var += 2; Local variable - Safe //. . this. i += 2; Not safe - Accessing a public member variable. Class. A o 1 = new Class. A(); Primitive- Safe x += 2; Thread t 1 = new Thread(new Task. A(o 1)); lst. element. At(2); Not Safe - Accessing a possible shared object (lst). t 1. start(); Foo. NUMBER = 4; //. . Not Safe (static - never safe!) local. Var = Foo. NUMBER ; Not Safe (static - never safe!) } }

Some Solutions • Thread-confined A thread-confined object is owned exclusively by and confined to

Some Solutions • Thread-confined A thread-confined object is owned exclusively by and confined to one thread, and can be modified only by the thread that owns it. • Shared read-only A shared read-only object can be accessed concurrently by multiple threads, but cannot be modified by any thread. Shared read-only objects are immutable.

Solution 1 - Thread Confinement • Problem is solved by not accessing the shared

Solution 1 - Thread Confinement • Problem is solved by not accessing the shared resources! By not having shared resources. • Called thread confinement: – threads access local resources only. • This way, no need to worry about thread safety since no thread can access any other thread’s variables.

Example //Thread. Confined public Car create. Car() { Engine e = new Fuel. Engine();

Example //Thread. Confined public Car create. Car() { Engine e = new Fuel. Engine(); List<Door> doors = new Linked. List<Door>(); doors. add(new Front. Door()); doors. add(new Back. Door()); Radio r = new AMFMRadio(); Car c = new Car(e, doors, r); return c; } //Not. Thread. Confined // e is not confined to this method - it is visible from the outside public Car create. Car(Engine e) { List<Door> doors = new Linked. List<Door>(); doors. add(new Front. Door()); doors. add(new Back. Door()); Radio r = new AMFMRadio(); Car c = new Car(e, doors, r); return c; }

Solution 2 - Immutability • An immutable object cannot be changed after construction. •

Solution 2 - Immutability • An immutable object cannot be changed after construction. • Solves thread safety problem by not allowing any variable modifications at all.

Immutable Class - conditions • All of its fields are final • The class

Immutable Class - conditions • All of its fields are final • The class is declared final (cannot be subclassed) • The this reference is not allowed to escape during construction. (the object is not fully constructed!) For more info: http: //www. ibm. com/developerworks/java/library/j-jtp 0618/ • Any fields that contain references to mutable objects, such as arrays, collections, or mutable classes like Date: – Are private – Are never returned or otherwise exposed to callers – Are the only reference to the objects that they reference – Do not change the state of the referenced objects after construction

/** * The constructed class is immutable even-though it consists of mutable objects. *

/** * The constructed class is immutable even-though it consists of mutable objects. * The class is immutable due to its design, not just by using the final keyword. * class Three. Stooges is declared to be final, which means that it cannot have subclasses. */ public final class Three. Stooges { private final Set<String> stooges = new Hash. Set<String>(); public Three. Stooges() { stooges. add("Moe"); stooges. add("Larry"); stooges. add("Curly"); } } public boolean is. Stooge(String name) { return stooges. contains(name); } it won't change after construction, meaning it won't be assigned with another reference, but still the object stooges is mutable: its internal values may change