Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

17
Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco

Transcript of Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

Page 1: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

Tutorial 2

Adventures in Threading

presented by:

Antonio Maiorano

Paul Di Marco

Page 2: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

Thread Scheduling in Java

• Execution of multiple threads in some order is called scheduling

• Java uses a simple, deterministic scheduling algorithm called fixed priority scheduling

• Threads of the same priority are chosen to run in round-robin fashion

Page 3: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

When Threads Run

• Current thread runs until one of following occurs:– Higher priority thread goes on the ready

queue (and thus, preempts current thread)– It yields, or it’s run() exits– On time-slicing supported systems, it’s time

allotment expires

Page 4: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

Programming Threads in Java

• There are four main functions of interest:– run() : the function the thread executes (you

provide this)– start() : creates a new thread and puts it on

the ready queue– join() : wait for this thread’s run() to complete– yield() : yields the cpu to the next thread

Page 5: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

So… why Java 1.2.1 ???

• Versions 1.2.1 and prior: Java VM controls thread scheduling, rather than the OS.

• Consequently:– No time-slicing– Does not take advantage of multiple

processors– Must call yield() to allow other threads to run

(of the same priority)

Page 6: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

Sample Thread Class// ThreadTest.java

class MyThread extends Thread { private String name;

public MyThread(String name) { this.name = name; }

public void run() { for (int i = 1; i <= 6; ++i) { System.out.println(name + ": " + i);

if (i == 3) yield(); // Let other threads run } }}

// CONTINUED…

Page 7: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

Sample Thread Programpublic class ThreadTest { public static void main(String[] args) { MyThread t1 = new MyThread("Alpha"); MyThread t2 = new MyThread("Beta");

// Schedule threads to start t1.start(); t2.start();

System.out.println("This is in the main()");

// Wait for threads to finish try { t1.join(); t2.join(); } catch (InterruptedException e) {}

System.out.println("End of main()"); }}

Page 8: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

Sample OutputThis is in the main()Alpha: 1Alpha: 2Alpha: 3Beta: 1Beta: 2Beta: 3Alpha: 4Alpha: 5Alpha: 6Beta: 4Beta: 5Beta: 6End of main()

Does this make sense?

Page 9: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

Programming Assignment 1

• class Block represents a typical stack

• class AcquireBlock represents the “pop” operation

• class ReleaseBlock represents the “push” operation

• Objective: to see what can happen if push and pop operations are not atomic.

• (Ms = main store – British terminology)

Page 10: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

public class Block { public static void main(String[] a) { System.out.println("Main thread starts executing."); System.out.println("Initial value of top = " + top + "."); System.out.println("Initial value of stack top = " + stack[top] + "."); System.out.println("Main thread will now fork two threads.");

AcquireBlock t1 = new AcquireBlock(); ReleaseBlock t2 = new ReleaseBlock(); t2.start(); // added to ready queue t1.start(); // added to ready queue

try { // main thread waits for thread termination t1.join(); t2.join(); } catch (InterruptedException e) { };

System.out.println("System terminates normally."); System.out.println("Final value of top = " + top + "."); System.out.println("Final value of stack top = " + stack[top] + "."); System.out.println("Final value of stack top-1 = " + stack[top-1] + "."); }}

class AcquireBlock extends Thread { ... }

class ReleaseBlock extends Thread { ... }

1

Page 11: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

public class Block { ... }

class AcquireBlock extends Thread { ... }

class ReleaseBlock extends Thread { public void run() { System.out.println("ReleaseBlock thread starts executing."); yield();

newtop = Block.top + 1;

System.out.println("ReleaseBlock increments pointer to " + newtop + ".");

Block.top++; yield();

System.out.println("ReleaseBlock thread returns Ms block " + block + " to position " + Block.top + ".");

Block.stack[Block.top] = block;

System.out.println("Rel: Current value of top = " + Block.top + "."); System.out.println("Rel: Current value of stack top = " + Block.stack[Block.top] + "."); System.out.println("ReleaseBlock thread terminates."); }}

2

Page 12: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

public class Block { ... }

class AcquireBlock extends Thread { public void run() { System.out.println("AcquireBlock thread starts executing."); yield();

System.out.println("AcquireBlock thread requests Ms block.");

oldtop = Block.top; copy = Block.stack[oldtop];

System.out.println("AcquireBlock thread obtains Ms block " + copy + " from position " + oldtop + ".");

block = Block.stack[oldtop]; newtop = Block.top - 1;

System.out.println("AcquireBlock decrements pointer to " + newtop + ".");

--Block.top;

System.out.println("Acq: Current value of top = " + Block.top + "."); System.out.println("Acq: Current value of stack top = " + Block.stack[Block.top] + "."); System.out.println("AcquireBlock thread terminates."); }}

class ReleaseBlock extends Thread { ... }

3

Page 13: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

public class Block { ... }

class AcquireBlock extends Thread { ... }

class ReleaseBlock extends Thread { public void run() { System.out.println("ReleaseBlock thread starts executing."); yield();

newtop = Block.top + 1;

System.out.println("ReleaseBlock increments pointer to " + newtop + ".");

Block.top++; yield();

System.out.println("ReleaseBlock thread returns Ms block " + block + " to position " + Block.top + ".");

Block.stack[Block.top] = block;

System.out.println("Rel: Current value of top = " + Block.top + "."); System.out.println("Rel: Current value of stack top = " + Block.stack[Block.top] + "."); System.out.println("ReleaseBlock thread terminates."); }}

4

Page 14: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

public class Block { ... }

class AcquireBlock extends Thread { public void run() { System.out.println("AcquireBlock thread starts executing."); yield();

System.out.println("AcquireBlock thread requests Ms block.");

oldtop = Block.top; copy = Block.stack[oldtop];

System.out.println("AcquireBlock thread obtains Ms block " + copy + " from position " + oldtop + ".");

block = Block.stack[oldtop]; newtop = Block.top - 1;

System.out.println("AcquireBlock decrements pointer to " + newtop + ".");

--Block.top;

System.out.println("Acq: Current value of top = " + Block.top + "."); System.out.println("Acq:Current value of stack top=" + Block.stack[Block.top]); System.out.println("AcquireBlock thread terminates."); }}

class ReleaseBlock extends Thread { ... }

5

Page 15: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

public class Block { ... }

class AcquireBlock extends Thread { ... }

class ReleaseBlock extends Thread { public void run() { System.out.println("ReleaseBlock thread starts executing."); yield();

newtop = Block.top + 1;

System.out.println("ReleaseBlock increments pointer to " + newtop + ".");

Block.top++; yield();

System.out.println("ReleaseBlock thread returns Ms block " + block + " to position " + Block.top + ".");

Block.stack[Block.top] = block;

System.out.println("Rel: Current value of top = " + Block.top + "."); System.out.println("Rel: Current value of stack top=" + Block.stack[Block.top]); System.out.println("ReleaseBlock thread terminates."); }}

6

Page 16: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

public class Block { public static void main(String[] a) { System.out.println("Main thread starts executing."); System.out.println("Initial value of top = " + top + "."); System.out.println("Initial value of stack top = " + stack[top] + "."); System.out.println("Main thread will now fork two threads.");

AcquireBlock t1 = new AcquireBlock(); ReleaseBlock t2 = new ReleaseBlock(); t2.start(); // added to ready queue t1.start(); // added to ready queue

try { // main thread waits for thread termination t1.join(); t2.join(); } catch (InterruptedException e) { };

System.out.println("System terminates normally."); System.out.println("Final value of top = " + top + "."); System.out.println("Final value of stack top = " + stack[top] + "."); System.out.println("Final value of stack top-1 = " + stack[top-1]); }}

class AcquireBlock extends Thread { ... }

class ReleaseBlock extends Thread { ... }

7

Page 17: Tutorial 2 Adventures in Threading presented by: Antonio Maiorano Paul Di Marco.

PA1 OutputMain thread starts executing.Initial value of top = 3.Initial value of stack top = d.Main thread will now fork two threads.ReleaseBlock thread starts executing.AcquireBlock thread starts executing.ReleaseBlock increments pointer to 4.AcquireBlock thread requests Ms block.AcquireBlock thread obtains Ms block $ from position 4.AcquireBlock decrements pointer to 3.Acq: Current value of top = 3.Acq: Current value of stack top = d.AcquireBlock thread terminates.ReleaseBlock thread returns Ms block e to position 3.Rel: Current value of top = 3.Rel: Current value of stack top = e.ReleaseBlock thread terminates.System terminates normally.Final value of top = 3.Final value of stack top = e.Final value of stack top-1 = c.