290 likes | 306 Views
Multithreaded Programming in Java. http://flic.kr/p/4Krva2. What is concurrent software?. A program with more than one thread of execution—more than one thing happens at once!. http://flic.kr/p/9ksxQa. Two Units of Execution. Process Has self-contained execution environment
E N D
Multithreaded Programming in Java http://flic.kr/p/4Krva2
What is concurrent software? A program with more thanone thread of execution—morethan one thing happens at once! http://flic.kr/p/9ksxQa
Two Units of Execution • Process • Has self-contained execution environment • Processes do not share memory (variables) • Interact via some form of message passing • Thread • AKA lightweight process • Every process has at least one (the main thread) • Faster to spawn than processes • Threads share parent processes resources (e.g., memory) • Threads interact by reading/writing variables Previously, you learned to do program processes with MPI Today, we’ll learn thread programming in Java
Consider this sequential program… public class MyMain { public static int x = 0; public static int y = 0; public static void main(String[] args) { x = 10; y = x + 10; x = y; y = 0; System.out.println("x=" + x + " y=" + y); } } What result would this program give? Answer: x=20 y=0
Consider this sequential program… public class MyMain { public static int x = 0; public static int y = 0; public static void main(String[] args) { x = 10; y = x + 10; x = y; y = 0; System.out.println("x=" + x + " y=" + y); } } What if you wanted these two sections to execute concurrently?
Concurrent program example public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } } What result would this program give?
Thread States Running Ready Blocked/Waiting Terminated
Concurrent program example x = 0 y = 0 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } } Initially, the main thread runs
Concurrent program example x = 0 y = 0 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } }
Concurrent program example x = 0 y = 0 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } } Executing start() spawns a new threadLet’s call it T1; initially, T1 is in the Ready state
Concurrent program example x = 0 y = 0 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } } Now, a context switch occurs
Concurrent program example x = 0 y = 0 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } } And T1 begins executing
Concurrent program example x = 10 y = 0 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } }
Concurrent program example x = 10 y = 0 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } } Another context switch occurs
Concurrent program example x = 10 y = 0 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } } And the main thread executes again
Concurrent program example x = 0 y = 0 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } }
Concurrent program example x = 0 y = 0 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } }
Concurrent program example x = 0 y = 0 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } }
Concurrent program example x = 0 y = 0 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } } Executing join() causes the main thread to enter the Blocking stateuntil all the threads it spawned terminate
Concurrent program example x = 0 y = 0 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } }
Concurrent program example x = 0 y = 10 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } }
Concurrent program example x = 0 y = 10 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } } T1 finishes executing and enters the Terminated state
Concurrent program example x = 0 y = 10 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } } … which causes the main thread to unblock
Concurrent program example x = 0 y = 10 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } } … and eventually reenter the Running state
Concurrent program example x = 0 y = 10 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } }
Concurrent program example x = 0 y = 10 public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { x = 10; y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); x = y; y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } } Finally, the main thread terminates
Nondeterministic scheduling increases complexity considerably and causes nasty problems public class MyMain implements Runnable { private static volatile int x = 0; private static volatile int y = 0; public void run() { A: x = 10; B: y = x + 10; } public static void main(String[] args) throws … { Thread myT = new Thread(new MyMain()); myT.start(); C: x = y; D: y = 0; myT.join(); System.out.println("x=" + x + " y=" + y); } } Race condition: Some schedules produce errors
What possible results might this program return? public class MainThread { public static volatile int x = 0; public static void main(String[] args) throws … { Thread myT = new Thread(new MyThread()); if (x > 0) { x = 0; } else { x = 6; } myT.join(); System.out.println("x = " + x); } } public class MyThread implements Runnable { public void run() { MainThread.x += 5; MainThread.x -= 5; } } http://flic.kr/p/5dfuqL