Lect6_OOP.pptx (Object-Oriented Programming)
Document Details
Uploaded by UpbeatJasper6329
Arab Academy for Science and Technology
Dalia Sobhy, Noha Ghatwary
Tags
Summary
Lecture notes on multithreading and parallel programming in Java. The lecture includes definitions, thread states, creating threads, thread pools, and thread synchronization. Includes examples, code snippets, and explanations of race conditions.
Full Transcript
CC 316 Object Oriented Programming Lecture 6 – Multithreading and Parallel Programming Dalia Sobhy, Noha Ghatwary Threads Concept Multiple threads on multiple CPUs Multiple threads sharing a single CPU Multithreading Definition Is a Java fea...
CC 316 Object Oriented Programming Lecture 6 – Multithreading and Parallel Programming Dalia Sobhy, Noha Ghatwary Threads Concept Multiple threads on multiple CPUs Multiple threads sharing a single CPU Multithreading Definition Is a Java feature that allows concurrent execution of two or more parts of a program for maximum utilization of CPU. Each part of such program is called a thread. So, threads are light- weight processes within a process. Thread States A thread can be in one of five states: New, Ready, Running, Blocked, or Finished. Extends Implements Implements Runnable Interface Creating Tasks and Threads Objective: Create and run three threads: – The first thread prints the letter a 100 times. – The second thread prints the letter b 100 times. – The third thread prints the integers 1 through 100. EExt Extends Thread Class The Thread Class The Static yield() Method You can use the yield() method to temporarily release time for other threads. For example, suppose you modify the code in Lines 53-57 in TaskThreadDemo.java as follows: public void run() { for (int i = 1; i = 50) is printed, the print100 thread is put to sleep for 1 millisecond. The join() Method You can use the join() method to force one thread to wait for another thread to finish. For example, suppose you modify the code in Lines 53-57 in TaskThreadDemo.java as follows: The numbers after 50 are printed after thread printA is finished. isAlive(), interrupt(), and isInterrupted() The isAlive() method is used to find out the state of a thread. It returns true if a thread is in the Ready, Blocked, or Running state; It returns false if a thread is new and has not started or if it is finished. The interrupt() method interrupts a thread in the following way: If a thread is currently in the Ready or Running state, its interrupted flag is set; if a thread is currently blocked, it is awakened and enters the Ready state, and an java.io.InterruptedException is thrown. The isInterrupt() method tests whether the thread is The deprecated stop(), suspend(), and resume() Methods NOTE: The Thread class also contains the stop(), suspend(), and resume() methods. As of Java 2, these methods are deprecated (or outdated) because they are known to be inherently unsafe. You should assign null to a Thread variable to indicate that it is stopped rather than use the stop() method. Thread Priority Each thread is assigned a default priority of Thread.NORM_PRIORITY. You can reset the priority using setPriority(int priority). Some constants for priorities include Thread.MIN_PRIORITY Thread.MAX_PRIORITY Thread.NORM_PRIORITY Thread Pools Why we need Thread Pools? Why we need Thread Pools? Why we need Thread Pools? Why we need Thread Pools? Why we need Thread Pools? Why we need Thread Pools? Why we need Thread Pools? Why we need Thread Pools? Thread Pools Starting a new thread for each task could limit throughput and cause poor performance. A thread pool is ideal to manage the number of tasks executing concurrently. JDK 1.5 uses the Executor interface for executing tasks in a thread pool and the ExecutorService interface for managing and controlling tasks. ExecutorService is a subinterface of Executor. Creating Executors To create an Executor object, use the static methods in the Executors class. What is the ideal Pool Size? CPU-Intensive Task CPU-Intensive Task IO-Intensive Operation IO-Intensive Operation IO-Intensive Operation What's the ideal Pool Size? Thread Synchronization A shared resource may be corrupted if it is accessed simultaneously by multiple threads. For example, two unsynchronized threads accessing the same bank account may cause conflict. Step balance thread[i] thread[j] 1 0 newBalance = bank.getBalance() + 1; 2 0 newBalance = bank.getBalance() + 1; 3 1 bank.setBalance(newBalance); 4 1 bank.setBalance(newBalance); Example: Showing Resource Conflict Objective: Write a program that demonstrates the problem of resource conflict. Suppose that you create and launch one hundred threads, each of which adds a penny to an account. Assume that the account is initially empty. 41 Race Condition What, then, caused the error in the example? Here is a possible scenario: Step balance Task 1 Task 2 1 0 newBalance = balance + 1; 2 0 newBalance = balance + 1; 3 1 balance = newBalance; 4 1 balance = newBalance; ); The effect of this scenario is that Task 1 did nothing, because in Step 4 Task 2 overrides Task 1's result. Problem: Task 1 and Task 2 are accessing a common resource in a way that causes conflict. This is a common problem known as a race condition in multithreaded programs. A thread-safe class: if an object of the class does not cause a race condition in the presence of multiple threads. As demonstrated in the preceding example, the Account class is not thread-safe. The synchronized keyword To avoid race conditions, more than one thread must be prevented from simultaneously entering certain part of the program, known as critical region. The critical region is the deposit method. You can use the synchronized keyword to synchronize the method so that only one thread can access the method at a time. There are several ways to correct the previous, one approach is to make Account thread-safe by adding the synchronized keyword in the deposit method as follows: public synchronized void deposit(double amount) Synchronizing Instance Methods and Static Methods A synchronized method acquires a lock before it executes. Cases: Instance method: the lock is on the object for which the method was invoked. Static method: the lock is on the class. If one thread invokes a synchronized instance method (respectively, static method) on an object, the lock of that object (respectively, class) is acquired first, then the method is executed, and finally the lock is released. Another thread invoking the same method of that object (respectively, class) is blocked until the lock is released. Synchronizing Instance Methods and Static Methods With the deposit method synchronized, the preceding scenario cannot happen. If Task 2 starts to enter the method, and Task 1 is already in the method, Task 2 is blocked until Task 1 finishes the method. Synchronizing Tasks Synchronizing Statements Invoking a synchronized instance method of an object acquires a lock on the object, and invoking a synchronized static method of a class acquires a lock on the class. A synchronized statement can be used to acquire a lock on any object, not just this object, when executing a block of the code in a method. This block is referred to as a synchronized block. The general form of a synchronized statement is as follows: synchronized (expr) { statements; } The expression expr must evaluate to an object reference. If the object is already locked by another thread, the thread is blocked until the lock is released. When a lock is obtained on the object, the statements in the synchronized block are executed, and then the lock is released. Synchronizing Statements vs. Methods Any synchronized instance method can be converted into a synchronized statement. Suppose that the following is a synchronized instance method: public synchronized void xMethod() { // method body } This method is equivalent to public void xMethod() { synchronized (this) { // method body } } Famous Thread Synchronization Problems Producer/Consumer Problem Semaphores Deadlock 49 Thank you