Java Threads. COMP 585 Noteset #2 1

Similar documents
Introduction to Java Threads

Java Threads. Written by John Bell for CS 342, Spring 2018

Overview. CMSC 330: Organization of Programming Languages. Concurrency. Multiprocessors. Processes vs. Threads. Computation Abstractions

COMP346 Winter Tutorial 4 Synchronization Semaphores

Chapter 32 Multithreading and Parallel Programming

Overview. Processes vs. Threads. Computation Abstractions. CMSC 433, Fall Michael Hicks 1

Threads and Parallelism in Java

Java Threads. Introduction to Java Threads

Chair of Software Engineering. Java and C# in depth. Carlo A. Furia, Marco Piccioni, Bertrand Meyer. Java: concurrency

Multitasking Multitasking allows several activities to occur concurrently on the computer. A distinction is usually made between: Process-based multit

Performance Throughput Utilization of system resources

Computation Abstractions. Processes vs. Threads. So, What Is a Thread? CMSC 433 Programming Language Technologies and Paradigms Spring 2007

Animation Part 2: MoveableShape interface & Multithreading

Threads Questions Important Questions

Info 408 Distributed Applications Programming Exercise sheet nb. 4

CMSC 330: Organization of Programming Languages

Multiple Inheritance. Computer object can be viewed as

CMSC 132: Object-Oriented Programming II. Threads in Java

Note: Each loop has 5 iterations in the ThreeLoopTest program.

Only one thread can own a specific monitor

Multithreaded Programming

CS11 Java. Fall Lecture 7

Concurrent Programming using Threads

CS 351 Design of Large Programs Threads and Concurrency

Need for synchronization: If threads comprise parts of our software systems, then they must communicate.

Java s Implementation of Concurrency, and how to use it in our applications.

What is a thread anyway?

Programming Language Concepts: Lecture 11

public class Shared0 { private static int x = 0, y = 0;

CMSC 330: Organization of Programming Languages

THREADS AND MULTITASKING ROBOTS

ROBOTICS AND AUTONOMOUS SYSTEMS

JAVA and J2EE UNIT - 4 Multithreaded Programming And Event Handling

Advanced Concepts of Programming

Contents. G53SRP: Java Threads. Definition. Why we need it. A Simple Embedded System. Why we need it. Java Threads 24/09/2009 G53SRP 1 ADC

Object Oriented Programming. Week 10 Part 1 Threads

Basics of. Multithreading in Java

CMSC 433 Programming Language Technologies and Paradigms. Concurrency

Quiz on Tuesday April 13. CS 361 Concurrent programming Drexel University Fall 2004 Lecture 4. Java facts and questions. Things to try in Java

Concurrency in Java Prof. Stephen A. Edwards

Threads Chate Patanothai

B2.52-R3: INTRODUCTION TO OBJECT ORIENTATED PROGRAMMING THROUGH JAVA

Unit III Rupali Sherekar 2017

Multithread Computing

Principles of Software Construction: Concurrency, Part 2

Robotics and Autonomous Systems

Programming in Parallel COMP755

04-Java Multithreading

Threads & Timers. CSE260, Computer Science B: Honors Stony Brook University

7. MULTITHREDED PROGRAMMING

CMSC 330: Organization of Programming Languages. Threads Classic Concurrency Problems

Informatica 3. Marcello Restelli. Laurea in Ingegneria Informatica Politecnico di Milano 9/15/07 10/29/07

Chapter 19 Multithreading

CS 455: INTRODUCTION TO DISTRIBUTED SYSTEMS [THREADS] Frequently asked questions from the previous class survey

COMP31212: Concurrency A Review of Java Concurrency. Giles Reger

Unit - IV Multi-Threading

Multithreading using Java. Dr. Ferdin Joe John Joseph

Handouts. 1 Handout for today! Recap. Homework #2 feedback. Last Time. What did you think? HW3a: ThreadBank. Today. Small assignment.

The Dining Philosophers Problem CMSC 330: Organization of Programming Languages

Synchronization synchronization.

CS 159: Parallel Processing

IT 540 Operating Systems ECE519 Advanced Operating Systems

CMSC 330: Organization of Programming Languages. The Dining Philosophers Problem

Concurrent Programming Lecture 10

CMSC 433 Programming Language Technologies and Paradigms. Composing Objects

Programmazione Avanzata e Paradigmi Ingegneria e Scienze Informatiche - UNIBO a.a 2013/2014 Lecturer: Alessandro Ricci

COURSE 11 PROGRAMMING III OOP. JAVA LANGUAGE

Synchronization. CS 475, Spring 2018 Concurrent & Distributed Systems

CS180 Review. Recitation Week 15

CSCD 330 Network Programming

Multi-threaded programming in Java

Le L c e t c ur u e e 7 To T p o i p c i s c t o o b e b e co c v o e v r e ed e Multithreading

CS455: Introduction to Distributed Systems [Spring 2019] Dept. Of Computer Science, Colorado State University

Module - 4 Multi-Threaded Programming

Component-Based Software Engineering

Java Programming Lecture 23

Advanced Programming Concurrency

UNIT IV MULTITHREADING AND GENERIC PROGRAMMING

Multithreaded Programming

Multi-threading in Java. Jeff HUANG

CS 455: INTRODUCTION TO DISTRIBUTED SYSTEMS [THREADS] Frequently asked questions from the previous class survey

Last Class: Synchronization

CS 556 Distributed Systems

Resource management. Real-Time Systems. Resource management. Resource management

Real-Time and Concurrent Programming Lecture 4 (F4): Monitors: synchronized, wait and notify

CSCD 330 Network Programming

CST242 Concurrency Page 1

CS61B, Spring 2003 Discussion #17 Amir Kamil UC Berkeley 5/12/03

AP COMPUTER SCIENCE JAVA CONCEPTS IV: RESERVED WORDS

MultiThreading 07/01/2013. Session objectives. Introduction. Introduction. Advanced Java Programming Course

Module 6: Process Synchronization. Operating System Concepts with Java 8 th Edition

Advanced Java Programming Course. MultiThreading. By Võ Văn Hải Faculty of Information Technologies Industrial University of Ho Chi Minh City

Java Monitors. Parallel and Distributed Computing. Department of Computer Science and Engineering (DEI) Instituto Superior Técnico.

Exercise Session Week 8

Unit 4. Thread class & Runnable Interface. Inter Thread Communication

Handling Multithreading Approach Using Java Nikita Goel, Vijaya Laxmi, Ankur Saxena Amity University Sector-125, Noida UP India

Outline. Threads. Single and Multithreaded Processes. Benefits of Threads. Eike Ritter 1. Modified: October 16, 2012

COMPSCI 230 Threading Week8. Figure 1 Thread status diagram [

Computation Abstractions. CMSC 330: Organization of Programming Languages. So, What Is a Thread? Processes vs. Threads. A computer.

COMP30112: Concurrency Topics 4.1: Concurrency Patterns - Monitors

Transcription:

Java Threads The topic of threads overlaps the boundary between software development and operation systems. Words like process, task, and thread may mean different things depending on the author and the context. Here is a reasonable set of general definitions. A process is a single task running on an operating system with its own set of resources that can be scheduled to run on the CPU. It is sometimes called a heavyweight process to emphasize that it controls its own virtual address space that is not shared with other processes. A thread is a single flow of control that runs in the context of some heavyweight process. A thread by itself is not a complete OS-level process or task that can be independently scheduled to run on the CPU. It is sometimes called a lightweight process to emphasize that it does not control its own virtual address space, but instead shares it with possibly other threads inside a single heavyweight process. If two heavyweight processes wish to exchange information, they cannot do so through shared variables because they exist in separate address spaces, so there are no shared variables available. Instead, they exchange information through message passing primitives, provided by either the operating system directly or by a 3 rd party library such as OpenMPI. There is a specific kind of parallel hardware design that is well matched to parallel software that depends on work performed cooperatively by processes that use message passing and not shared memory. This architecture is called a loosely-coupled parallel architecture. This means a parallel architecture with multiple processors, each with its own local memory and no memory shared by all processors. If two threads wish to exchange information, they may do so through shared variables because they exist in a single common virtual address space. The parallel hardware architecture best suited for parallel software that uses multiple threads within a single process is different, it is called a tightly-coupled architecture. It means an architecture with multiple processors but a common shared memory area. Different threads can run on different processors but they all have access to the same common shared memory. If a multithreaded process is running on a uniprocessor then there can only be virtual parallelism since only one thread within one process can be running at a time. But if a multithreaded application is running on a shared-memory multiprocessor (or even a uniprocessor with multiple cores), it is possible that multiple threads within the same process may run simultaneously. For that reason, a multithreaded application will have to make correct use of synchronization primitives that are built into the thread library to ensure program correctness. This is a hard problem to implement correctly. In the context of the development of a multithreaded software application, any code execution must be supported by some thread. In Java, the JVM automatically creates a thread called the main thread to run the main method of any Java program. You get this thread automatically, and might not have even noticed it. The state of the current Thread can be manipulated in a simple way via the static method Thread.sleep(int msec); Example for (int i=1; i<=100; i++) { System.out.println( i = + i); Thread.sleep(1000); // sleep (delay) for approx 1000 msec = 1 sec Note: we re putting a major thread to sleep here, normally would do this only for an auxiliary thread that we create expressly for that purpose. COMP 585 Noteset #2 1

The sleep method causes the current thread to suspend execution and wait for a timer interrupt from the OS. It also generates a checked (non-runtime) exception of type InterruptedException, so the complete example is actually: for (int i=1; i<=100; i++) { System.out.println("i = " + i); try { Thread.sleep(1000); catch (InterruptedException e) { System.out.println("Got Interrupted!"); Short Review of Exceptions A runtime exception is also called an unchecked exception. It means that the Java compiler does not require the exception to be handled via try/catch or passed to another handler via throw. The expectation is that an unchecked exception should be implicitly avoided by direct modification of the software (e.g., integer divide by zero). A nonruntime exception is also called a checked exception. It means that the Java compiler does require the exception to either be immediately handled with try/catch, or the containing method to be marked with a throws clause, which passes the exception to a try/catch block at some earlier point in the call chain. Non-runtime exceptions usually indicate exceptions that are inherent in the software which cannot be eliminated by changes to the code. Instead they must be properly responded to or handled by try/catch or throws. Any object that extends class Thread or implements interface Runnable can be launched as a separate thread. The code that defines the behavior of the thread is the run() method. If one thread that creates a second thread, the first thread must instantiate the second thread and then call its start() method (not its run() method). Threads and Swing The main method, and any method in its call chain, runs on the main thread. The JVM creates a main thread on behalf of any main method that it is asked to execute. Methods of an event listener, and any methods in their call chain, run on the event thread. The event thread is automatically introduced into a running application whenever a GUI component is instantiated. Other threads that the programmer needs must be created. Programs with User-Created Threads A program can create its own multiple threads by either Defining a new class that extends class Thread Having an existing class implement the Runnable interface In either case, the Thread must provide a definition for the method This defines the code to be executed by the Thread. After a Thread has been created (instantiated), it is launched by calling its start() method. If the run() method is called directly, no concurrency is achieved, the run() method joins the call chain of the current thread. The start() method is intercepted by the JVM, which creates a new Thread, and assigns the run() method to run on that new Thread. COMP 585 Noteset #2 2

Example: public class Thr { Thread t1 = new Thread() { System.out.println("t1 starts, sleeps for 3"); try { Thread.sleep(3000); catch (InterruptedException e) { System.out.println("t1 done!"); ; Thread t2 = new Thread() { System.out.println("t2 starts, sleeps for 5"); try { Thread.sleep(5000); catch (InterruptedException e) { System.out.println("t2 done!"); ; t2.start(); try { Thread.sleep(1000); catch (InterruptedException e) { t1.start(); Output is t2 starts, sleeps for 5 t1 starts, sleeps for 3 t1 done! t2 done! Threads t1 and t2 are each instantiated as objects of anonymous subclass of class Thread. The run() method is overridden as part of the instantiation to define the characteristic behavior of each thread. The main method launches the threads by invoking their start() methods, not the run() methods directly. Thread t2 begins executing before Thread t1. But the longer sleep time causes Thread t2 to still finish last. In this example, there is no real interaction or synchronization between the threads. The threads are controlled only by their interaction with the system clock. Synchronization gives the user more detailed control over how the threads interact with each other. COMP 585 Noteset #2 3

Thread Synchronization In Java a Thread represents a flow of control for some code. an Object (any Object) represents a lock that can be used for synchronization between Threads. Every Java Object contains an object-level lock that can be used for synchronization between multiple threads. In other words, multiple threads can synchronize their execution by waiting on and signaling a specific object that has been created to act as a lock, guard, semaphore, or other synchronization point. One thread can also interact directly with another thread, but there are new limits on the operations that can be performed. If you look at the API, you will see many deprecated methods for class Thread, which reflects the fact that Java s earlier model for threads and synchronization was broken. Many methods that directly modify the state of a thread are now known to be thread unsafe and are deprecated. Deprecated methods are still supported for backward compatibility with older code, but they should not be used in new code. In summary, here are the operations for Objects and Threads related to synchronization: Class Object wait() // executing Thread is suspended awaiting a later notify notify() // waiting Thread at the head of the wait queue is reactivated notifyall() // all waiting Threads in the wait queue are reactivated Class Thread start() // used by an executing Thread to activate another Thread interrupt() // used by an executing Thread to deactivate another Thread sleep(int) // note: static method called by some Thread on behalf of itself In particular note that destroy() resume() stop() suspend() are all deprecated. Since the individual Threads in a multithreaded application run independently of each other, the programmer must have the ability to guarantee in some situations that Thread #1 doesn t go past point A before Thread #2 reaches point B. In order to control progress, a Thread may perform a wait() operation on some Object acting as a lock or semaphore. In order for the waiting Thread to finish its wait, another Thread must perform a notify() operation on the same Object. Lock Provides synchronization features that can be used to coordinate execution of threads. Any Java object can be used as a lock. Each object provides an object-level lock, and each class provides a class-level lock. The most common synchronization operations are wait() and notifyall(). COMP 585 Noteset #2 4

Synchronization Example #1 In this example, the current thread synchronizes on an object-level lock which is nested inside the try-catch block for the InterruptedException. In this case, the thread releases the lock on the object as soon as it is interrupted. try { synchronized(obj) { obj.wait(); catch (InterruptedException e) { This example minimizes the amount of time the thread spends owning or controlling the object-level lock. For many applications, however, this won t be as useful as the next example. Synchronization Example #2 In this example, the try-catch block is nested inside the synchronized block. synchronized(obj) { try { obj.wait(); catch (InterruptedException e) { // mutex code goes here This example is more typical for guarding a mutex region, which could go into the catch block, or after the catch block while still inside the synchronized block. Still, there is a subtle problem (potential problem) with this example, since a Thread that is interrupted after waiting can be interrupted for different reasons, not all of which may be related to the object lock that it originally waited on. The notify() vs. notifyall() Methods General recommendation is for a signaling thread to signal via notifyall(), and release all threads that are waiting on an object-level lock. The released threads should then all compete among themselves to reacquire the lock. The next example implements a producer-consumer application that supports any number of producers and consumers using this approach. COMP 585 Noteset #2 5

Example (simplified initial version, not complete): class Thr2 { final Object obj = new Object(); Thread t1 = new Thread() { System.out.println("t1 starts, notifies t2"); obj.notify(); System.out.println("t1 done!"); ; Thread t2 = new Thread() { System.out.println("t2 starts, waits on t1"); obj.wait(); System.out.println("t2 done!"); ; t2.start(); Thread.sleep(5000); t1.start(); Problems First, the wait() and sleep() method calls generate an InterruptedException, so they must use try/catch. This is a compile-time error because InterruptedException is a checked or non-runtime exception. Correction #1 try { obj.wait(); catch (InterruptedException e)_ { Second, both the wait() and notify() methods must correctly negotiate the acquisition of the object-level lock before actually performing the wait or the notify. This requires that the code be placed into a synchronized block associated with the object. The code from correction #1 compiles, but generates a runtime exception of type IllegalMonitorStateException. COMP 585 Noteset #2 6

Using these observations to complete the example, we get: class Thr2 { final Object obj = new Object(); Thread t1 = new Thread() { System.out.println("t1 starts, notifies t2"); synchronized(obj) { obj.notify(); System.out.println("t1 done!"); ; Thread t2 = new Thread() { System.out.println("t2 starts, waits on t1"); try { synchronized(obj) { obj.wait(); catch(interruptedexception e) { System.out.println("t2 done!"); ; t2.start(); try { Thread.sleep(5000); catch (InterruptedException e) { t1.start(); Output is t2 starts, waits on t1 t1 starts, notifies t2 t1 done! t2 done! COMP 585 Noteset #2 7

Multithreaded Message Drop Box (from http://java.sun.com/docs/books/tutorial/essential/concurrency/guardmeth.html) Imagine an object that represents a simple String message to be sent or received, along with a boolean flag to indicate if there is a message present or not. public class Drop { private String message; private boolean empty = true; Create synchronized methods that allow a consumer to pick up a message or a producer to drop off a message. The flag must be toggled accordingly. Since multiple producers and consumers might be present, all pick ups and drop offs must be synchronized on the object-level lock for the Drop object. [note: a synchronized non-static method implicitly uses the current object ( this ) as the lock] public class Drop { public synchronized String take() { while (empty) { try { wait(); catch (InterruptedException e) { empty = true; notifyall(); return message; public synchronized void put(string message) { while (!empty) { try { wait(); catch (InterruptedException e) { empty = false; this.message = message; notifyall(); Picking Up a Message In order to pick up a message ( take ) from this object, the taking thread applies the take() method to the Drop object. Since the method is synchronized, the thread has exclusive access to the object. If the message is present (empty == false), the thread picks it up, toggles the empty flag, and signals all waiting threads. If the message is not present, the thread waits in the object s queue, and releases the lock (this happens automatically as part of the wait). Dropping Off a Message The putting thread applies the put() method to the Drop object, which also synchronizes and gives the putting thread exclusive access to the object. If the previous message has already been picked up (empty == true), the thread drops off the message, toggles the flag, and signals all waiting threads. If the previous message has not been picked up, the thread waits in the queue and releases the lock. In all cases, when a waiting thread is signaled, it automatically reacquires the object lock before proceeding. COMP 585 Noteset #2 8