Practical Session 6 Multitasking vs. multithreading Threads Concurrency vs. Parallelism Java Threads...
-
Upload
denzel-chantry -
Category
Documents
-
view
258 -
download
2
Transcript of Practical Session 6 Multitasking vs. multithreading Threads Concurrency vs. Parallelism Java Threads...
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.– 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.
• 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 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
Copyright © 2002, DeLorme
Concurrency vs. ParallelismCPU CPU1 CPU2
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 <className> implements Runnable {
public void run(){//the “main” function of the 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.
class SimpleRunnable implements Runnable { private String name;
SimpleRunnable(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.printStackTrace();}
} }}
Wrapped by a Thread- Threads01.java
public class Threads01 {//creates to simeRunnable threads and starts thempublic static void main(String[] a) {
SimpleRunnable r1 = new SimpleRunnable("r1");Thread t1 = new Thread(r1);
SimpleRunnable r2 = new SimpleRunnable("r2");Thread t2 = new Thread(r2);
t1.start();t2.start();
}}
The order of start does not guarantee the order of execution.
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:• ExecutorService e = Executors.newFixedThreadPool(<numberOfThreads>);
– numberOfThreads: 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 - Threads01e.javaclass SimpleRunnable implements Runnable { private int m_number;
public SimpleRunnable(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 Threads01e { public static void main(String[] a) { // Create an executor: ExecutorService e = Executors.newFixedThreadPool(3);
// create 10 runnables, and execute them. for(int i=0;i<10;i++) { System.out.println("creating a new task: " + i + " "); SimpleRunnable r = new SimpleRunnable(i); e.execute(r); } e.shutdown(); }}
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 same place", can be dangerous.
• The two tasks can interfere with each other, and unexpected results might occur.
Example – shared counterpublic class Counter{
private int fCounter;
public Counter(){fCounter = 0;
}
public void increment(){fCounter++;
}
public int getValue(){return fCounter;
}}
public class Incrementer implements Runnable { Counter fCounter;
Incrementer(Counter ctr) { fCounter = ctr; }
/** * Main lifecycle. * increment the counter 200 times then dies. */ public void run() { for (int i = 0; i<200; i++) { fCounter.increment(); } }}
public class Threads03{
// 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 t1 = new Thread(new Incrementer(ctr));Thread t2 = new Thread(new Incrementer(ctr));
t1.start();t2.start();//wait until their job is donewhile (t1.isAlive() || t2.isAlive()); //wait until all done.
//print out result of attempt iSystem.out.println("Attempt " + i + ", total value: " +
ctr.getValue());}
} }}
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 ClassA { public long i; public Vector v; public ClassA() { /* ... */ } public void doSomething(long x, List lst) { long localVar = 0; Object o; o = this.v.elementAt(2); localVar += 2; this.i += 2; x += 2; lst.elementAt(2); Foo.NUMBER = 4; localVar = Foo.NUMBER ; }}
class TaskA implements Runnable { //... private ClassA a; private List lst; public long r; public void run() { this.r = 2; this.a.doSomething(9, lst); }} class Main { public static void main(String[] args) { // .... ClassA o1 = new ClassA(); Thread t1 = new Thread(new TaskA(o1)); t1.start(); // .... }}
Not safe - Accessing a public member variable.
Local variable - SafeNot safe - Accessing a public member variable.Primitive- Safe
Not Safe - Accessing a possible shared object (lst).Not Safe (static - never safe!)
Not Safe (static - never safe!)
Not safe - Accessing a public member variable.
Not Safe - The private member variable (lst) is exposed to class A.
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 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//ThreadConfined public Car createCar() { Engine e = new FuelEngine(); List<Door> doors = new LinkedList<Door>(); doors.add(new FrontDoor()); doors.add(new FrontDoor()); doors.add(new BackDoor()); doors.add(new BackDoor()); Radio r = new AMFMRadio(); Car c = new Car(e, doors, r); return c; }
//NotThreadConfined// e is not confined to this method - it is visible from the outside public Car createCar(Engine e) { List<Door> doors = new LinkedList<Door>(); doors.add(new FrontDoor()); doors.add(new FrontDoor()); doors.add(new BackDoor()); doors.add(new BackDoor()); Radio r = new AMFMRadio(); Car c = new Car(e, doors, r); return c; }
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 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-jtp0618/
• 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 class is immutable due to its design, not just by using the final keyword. * class ThreeStooges is declared to be final, which means that it cannot have subclasses. */
public final class ThreeStooges { private final Set<String> stooges = new HashSet<String>();
public ThreeStooges() { stooges.add("Moe"); stooges.add("Larry"); stooges.add("Curly");
}
public boolean isStooge(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