Threads CS 3250 Some of these slides contain

  • Slides: 31
Download presentation
Threads CS 3250 Some of these slides contain material by Professor Chuck Allison

Threads CS 3250 Some of these slides contain material by Professor Chuck Allison

What is a thread? s an independent unit of execution within a process s

What is a thread? s an independent unit of execution within a process s a path of execution through a program s a "lightweight process"

Sharing (or not) s Threads share the same address space and share the heap

Sharing (or not) s Threads share the same address space and share the heap s + Easy to communicate with other threads s - Possibility of inconsistent states s Each thread has its own execution stack

Multi-threaded vs. Single-threaded Advantages of using more than one thread: s Single-threaded processes can't

Multi-threaded vs. Single-threaded Advantages of using more than one thread: s Single-threaded processes can't easily handle concurrent activities s e. g. , waiting for user I/O, network I/O, and doing calculations at the same time s Better performance if more than one processor s No guarantees s Can sometimes get better performance even if there's only one CPU. How?

Multi-threaded vs. Single-threaded Disadvantages of using more than one thread: s Race conditions and

Multi-threaded vs. Single-threaded Disadvantages of using more than one thread: s Race conditions and deadlock s One thread can accidentally modify another's resources. s Have to deal with synchronization. s Concurrency can lead to worse performance rather than better.

Pitfalls s Watch out for libraries that aren’t thread -safe s Don’t make any

Pitfalls s Watch out for libraries that aren’t thread -safe s Don’t make any assumptions about when threads will execute. s Don’t use reasoning like “that will hardly ever happen”. s Testing is necessary but not sufficient. s Test on a variety of systems.

Pitfalls s Only use threads when appropriate. s “Fortunately, correct programs are frequently the

Pitfalls s Only use threads when appropriate. s “Fortunately, correct programs are frequently the simplest and have the most elegant design. Complexity should be avoided wherever possible. ” Windows System Programming, p. 223

A First Example // Illustrates Independent Threads class My. Thread extends Thread { private

A First Example // Illustrates Independent Threads class My. Thread extends Thread { private int count; public My. Thread(String name, int count) { super(name); // Optional thread name this. count = count; } public void run() { for (int i = 0; i < count; ++i) System. out. println(get. Name()); } } Example by Professor Chuck Allison

Main program launches 2 threads public class Independent { public static void main(String[] args)

Main program launches 2 threads public class Independent { public static void main(String[] args) { Thread t 1 = new My. Thread("Dessert. Topping", 8); Thread t 2 = new My. Thread("Floor. Wax", 4); t 1. start(); t 2. start(); } } Define run(), call start()

Output (Dependent on platform and environment - YMMV) Dessert. Topping Floor. Wax Dessert. Topping

Output (Dependent on platform and environment - YMMV) Dessert. Topping Floor. Wax Dessert. Topping

The Runnable Interface s Alternative to extending java. lang. Thread s Declares a run(

The Runnable Interface s Alternative to extending java. lang. Thread s Declares a run( ) method s 2 virtues: s Separates task from thread objects s Leaves you free to extend another class s Java only supports single inheritance s Thread has a constructor that takes a Runnable object

The Runnable interface class My. Task implements Runnable { private int count; private String

The Runnable interface class My. Task implements Runnable { private int count; private String name; public My. Thread(String name, int count){ this. count = count; this. name = name; } } public void run(){ for (int i = 0; i < count; ++i) System. out. println(name); }

Create threads from Runnable objects public class Independent. R { public static void main(String[]

Create threads from Runnable objects public class Independent. R { public static void main(String[] args) { Thread t 1 = new Thread( new My. Task("Dessert. Topping", 8)); Thread t 2 = new Thread( new My. Task("Floor. Wax", 4)); t 1. start(); t 2. start(); } }

Blocking I/O s Note that the calls to println( ) run uninterrupted s I/O

Blocking I/O s Note that the calls to println( ) run uninterrupted s I/O is a blocking operation s The thread waits until it completes s Other threads may run, but the I/O will be undisturbed s Reason: I/O is coarse-grained native code s JDK 1. 4 java. nio provides non-blocking I/O s Buffers, channels, selectors, for more fine-grained control s One thread can manage multiple connections

Interleaved I/O class My. Thread extends Thread { // <snip> public void run() {

Interleaved I/O class My. Thread extends Thread { // <snip> public void run() { for (int i = 0; i < count; ++i) { display(); // Replaces println() } } void display() { String s = get. Name(); for (int i = 0; i < s. length(); ++i) System. out. print(s. char. At(i)); System. out. println(); } } Example by Professor Chuck Allison

Output (interleaved – oops!) Dessert. Topping DFloor. Wax Floor. Wessert. Topping Desax sert. Topping

Output (interleaved – oops!) Dessert. Topping DFloor. Wax Floor. Wessert. Topping Desax sert. Topping Dessert. Topping

Race Condition result of executing program(s) depends on who runs precisely when balance starts

Race Condition result of executing program(s) depends on who runs precisely when balance starts at 1000 Thread 1 b = get. Balance(“ 1234”); Thread 2 b = get. Balance(“ 1234”); b += 500; set. Balance(“ 1234”, b); b -= 100; set. Balance(“ 1234”, b); What should the ending balance be? What will it be? Will getting rid of the local variable b solve the problem? How can we solve this problem?

Synchronization s Need to prevent race conditions s Critical region s Part of a

Synchronization s Need to prevent race conditions s Critical region s Part of a program that accesses shared memory (or another shared resource) s To prevent race conditions, only allow one thread at a time to enter critical region

Locks and Monitors s Every object has a hidden lock object s Used to

Locks and Monitors s Every object has a hidden lock object s Used to protect code blocks s Monitor concept s Only allows one thread in at a time s Thread acquires a lock via some object s Other related threads wait until lock is released s Applies to all guarded methods for that object only s Achieved with the synchronized keyword s Protects code (not data directly) s Make data private!

How synchronized works (conceptually) synchronized void f() { <protected code> } is the same

How synchronized works (conceptually) synchronized void f() { <protected code> } is the same as the following pseudocode… void f() { this. lock. acquire(); try { <protected code> } finally Very important. { this. lock. release(); } } Why?

Library Example s Check-out system s Usually solved by database locks, but humor me

Library Example s Check-out system s Usually solved by database locks, but humor me s Book class s Must only allow one thread access to check-out check-in code s Synchronized methods

// Illustrates synchronized methods class Book { private final String title; private final String

// Illustrates synchronized methods class Book { private final String title; private final String author; private String borrower; public Book(String title, String author) { this. title = title; this. author = author; borrower = null; } public synchronized boolean check. Out(String borrower) { if (is. Available()) { this. borrower = borrower; return true; } else return false; }

public synchronized boolean check. In() { if (!is. Available()) { borrower = null; return

public synchronized boolean check. In() { if (!is. Available()) { borrower = null; return true; } else return false; } public String get. Title() { return title; } public String get. Author() { return author; }

public synchronized boolean is. Available() { return borrower == null; } } public synchronized

public synchronized boolean is. Available() { return borrower == null; } } public synchronized String get. Borrower() { return borrower; }

Principles s Always make data private s Always protect access to shared data with

Principles s Always make data private s Always protect access to shared data with a monitor (i. e. , using synchronized) s Synchronize as little code as possible s Blocks instead of entire methods: s {… synchronized (obj) {…} … }

Synchronizing display class My. Thread extends Thread { private static Object lock = new

Synchronizing display class My. Thread extends Thread { private static Object lock = new Object(); // <snip> } void display() { synchronized(lock) { String s = get. Name(); for (int i = 0; i < s. length(); ++i) System. out. print(s. char. At(i)); System. out. println(); } }

Output (not interleaved) Dessert. Topping Floor. Wax Dessert. Topping

Output (not interleaved) Dessert. Topping Floor. Wax Dessert. Topping

A simpler way of synchronizing display synchronized static void display(String s) { for (int

A simpler way of synchronizing display synchronized static void display(String s) { for (int i = 0; i < s. length(); ++i) System. out. print(s. char. At(i)); System. out. println(); } Will use lock on class object

Threads and Exceptions s Exceptions belong to a thread s Both are stack-based s

Threads and Exceptions s Exceptions belong to a thread s Both are stack-based s When an exception occurs in a monitor, the lock is released s For uncaught exceptions, the current thread dies s Thread. Group. uncaught. Exception() is called, which prints the stack trace as its default behavior

Deadlock s Circular wait s e. g. , Breakfasting Kindergarteners, pirate map s Order

Deadlock s Circular wait s e. g. , Breakfasting Kindergarteners, pirate map s Order access to resources s All or nothing requests for resources s Must get everything requested or nothing

Threads with Java. FX s Java. FX GUIs should only be updated from the

Threads with Java. FX s Java. FX GUIs should only be updated from the application thread. s Use Platform. run. Later to execute code on the application thread: Platform. run. Later(() -> lbl. Text. set. Text(text)); Introduction to Java, Daniel Liang, p. 33 -10