210 likes | 301 Views
Presentation of Practical Exercise 1. Threads in Java Mutual exclusion in Java. TDT4186, H2008. Thread Concept. A thread is an independent path of execution within a program, or a specific task. Multithreading refers to two or more tasks executing concurrently within a single program.
E N D
Presentation of Practical Exercise 1 Threads in Java Mutual exclusion in Java TDT4186, H2008
Thread Concept • A thread is an independent path of execution within a program, or a specific task. • Multithreading refers to two or more tasks executing concurrently within a single program. • E.g. word processing (type characters and check spelling at the same time) • Multiprocessor systems: multiple threads can be executed simultaneously. • Single-processor systems: • Threads share CPU time. • The operating system is responsible for scheduling and allocating resources to them.
Thread Concept Multiple threads on multiple CPUs Multiple threads sharing a single CPU
Thinking about threads • Threads are lightweight compared to processes. • Allow different tasks to be performed concurrently. • In reality, the different threads’ statements are interleaved. • Share the process’s resources, e.g. code, data and open files. • Context switching between threads is usually less expensive than between processes. • Intercommunication among threads is potentially problematic.
Threads in Java • In Java, you start with just one thread, called the main thread. • The main thread • Able to create additional threads • Executed by invoking a main() method • Terminated when the main() method returns • Types of threads • A user-made thread • Two ways of creating: implement Runnable interface, or extend Thread class • The main thread invokes Thread.start() in order to start a new thread • Executed by the code in a run() method • Terminated when the run() method returns • An event handler thread • Started by the API when a GUI is created • A garbage collection thread • Started by the JVM
Creating a thread • When you start a program you start the main thread. • To start more threads: public static void main(String[] args) { Courier courier = new Courier(); courier.start(); for(int i = 0; i < 15; i++) { System.out.println(”Blah”); } } public class Courier extends Thread { […] public void run () { for(int i = 0; i < nofVisits; i++) { bank.depositMoney(100); } } } • At the courier.start() statement the executing thread (the main thread) branches into two threads, indicated by the blue (main) and red (courier) arrow.
Equivalent method: public static void main(String[] args) { Courier courier = new Courier(); Thread t = new Thread(courier); t.start(); for(int i = 0; i < 15; i++) { System.out.println(”Blah”); } } public class Courier implements Runnable { […] public void run () { for(int i = 0; i < nofVisits; i++) { bank.depositMoney(100); } } }
What is mutual exclusion? • Mutual exclusion is about guaranteeing that a resource is only accessed by one user at a time. • In our case, the resource is a code segment, and the users are threads. • Code that must be mutually exclusive is called critical code.
When is code critical? • When multiple threads may execute a code segment, and • the code segment performs some operation that consists of multiple statements but must be treated as an atomic operation. • Similar to a transaction in database systems. • Violation of the mutual exclusion requirement can lead to data inconsistencies. • Example (critical code marked with red): public class Money { private int balance = 1000; public void addMoney(int t) { int temp = balance; temp += t; balance = temp; } }
The three statements in the addMoney() method are critical code. Example of serial execution:
The three statements in the addMoney() method are critical code. Example of what could go wrong if the code isn’t treated as an atomic unit:
We see from the example that the variables balance gets wrong value (they should sum to 1100) because two threads are modifying them simultaneously. • Solutions: • Write ”smarter” code. • Protect critical sections of the code with mutual exclusion. • Code where these solutions have been applied is called threadsafe because it is safe to have multiple threads executing the code.
Avoiding critical code • In some cases it is possible to perform operations in such a way that interleaving of statements is not a problem. • Example: public class Money { private int balance = 1000; public void addMoney(int t) { balance += t; } }
Enforcing mutual exclusion • If critical code is unavoidable, mutual exclusion must be enforced with locks. • In Java, this is done using the synchronized keyword. public class Money { private int balance = 1000; public synchronized void addMoney(int t) { int temp = balance; temp += t; balance = temp; } }
The synchronized keyword • Used to indicate that a thread must acquire a lock before proceeding. • When the thread leaves the section of the code marked as synchronized, it releases the lock, allowing waiting threads to enter. • Only one thread can have the lock at any time, so only one thread can be inside a synchronized block at any time. • Different synchronized blocks may use the same lock. • More on the synchronized keyword in exercise 2.
The exercise • Your task is to inspect a small, multithreading program. • Couriers deposit money in a bank. • Each courier is a thread. • Somehow, the total amount of money deposited differs from the amount of money actually in the bank. • This is because the program isn’t threadsafe.
Your task • Analyse the code, find out why it doesn’t work. Correct the error(s). • Compare the runtime of the correct solution to the runtime of the original code. Explain any differences. • Show examples of situations where the incorrect code leads to inconsistent money accounts.
Hints • Take advantage of examples and information given in this presentation. • You should run the incorrect program to get an impression of what the program does, and to see for yourself that inconsistencies sometimes occur. • You can run the handed out code by running the P1.bat batch file.