Java Threads. Introduction Process 1 Processes and Threads Environment Stack Code Heap CPU State Process 2 Environment Stack Code Heap CPU State.

Slides:



Advertisements
Similar presentations
Concurrent Programming Abstraction & Java Threads
Advertisements

Background Concurrent access to shared data can lead to inconsistencies Maintaining data consistency among cooperating processes is critical What is wrong.
Ade Azurat, Advanced Programming 2004 (Based on LYS Stefanus’s slides) Advanced Programming 2004, Based on LYS Stefanus’s slides Slide 2.1 Multithreading.
1 CSC321 §2 Concurrent Programming Abstraction & Java Threads Section 2 Concurrent Programming Abstraction & Java Threads.
Liang, Introduction to Java Programming, Seventh Edition, (c) 2009 Pearson Education, Inc. All rights reserved Chapter 5 Multithreading and.
Algorithm Programming Concurrent Programming in Java Bar-Ilan University תשס"ח Moshe Fresko.
Multithreading The objectives of this chapter are:
1 Java Threads Representation and Management of Data on the Internet.
1 Thread Pools Representation and Management of Data on the Internet.
1 Threads. 2 Introduction s/index.html
Java Threads Representation and Management of Data on the Internet.
Synchronization in Java Fawzi Emad Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
Threads A thread is a program unit that is executed independently of other parts of the program A thread is a program unit that is executed independently.
Definitions Process – An executing program
Multithreading in Java Nelson Padua-Perez Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
1 Thread Pools. 2 What’s A Thread Pool? A programming technique which we will use. A collection of threads that are created once (e.g. when server starts).
Threads Written by Amir Kirsh, Dr. Yaron Kanza. Edited by Liron Blecher.
Multithreading.
Parallel Processing (CS526) Spring 2012(Week 8).  Thread Status.  Synchronization in Shared Memory Programming(Java threads ) ◦ Locks ◦ Barriars.
1 CSCD 330 Network Programming Lecture 13 More Client-Server Programming Sometime in 2014 Reading: References at end of Lecture.
Internet Software Development More stuff on Threads Paul Krause.
Object Oriented Programming Lecture 8: Introduction to laboratorial exercise – part II, Introduction to GUI frames in Netbeans, Introduction to threads.
Threads. Java Threads A thread is not an object A thread is a flow of control A thread is a series of executed statements A thread is a nested sequence.
Threads in Java. History  Process is a program in execution  Has stack/heap memory  Has a program counter  Multiuser operating systems since the sixties.
Quick overview of threads in Java Babak Esfandiari (extracted from Qusay Mahmoud’s slides)
Multithreading in Java Project of COCS 513 By Wei Li December, 2000.
Today’s Agenda  Quick Review  Finish Java Threads  The CS Problem Advanced Topics in Software Engineering 1.
Java Threads DBI – Representation and Management of Data on the Internet.
111 © 2002, Cisco Systems, Inc. All rights reserved.
1 CMSC 341: Data Structures Nilanjan Banerjee Data Structures University of Maryland Baltimore County
Multithreading : synchronization. Avanced Programming 2004, Based on LYS Stefanus’s slides slide 4.2 Solving the Race Condition Problem A thread must.
1 (Worker Queues) cs What is a Thread Pool? A collection of threads that are created once (e.g. when a server starts) That is, no need to create.
1 cs Process 1 Processes and Threads Environment Stack Code Heap CPU State Process 2 Environment Stack Code Heap CPU State cs
Multithreading in Java Sameer Singh Chauhan Lecturer, I. T. Dept., SVIT, Vasad.
Introduction to Threads Session 01 Java Simplified / Session 14 / 2 of 28 Objectives Define a thread Define multithreading List benefits of multithreading.
Advanced Programming 2004, based on LY Stefanus’s slides slide 8.1 Multithreading : Thread Scheduling ThreadGroup.
Multithreading in JAVA
Threads Doing Several Things at Once. Threads n What are Threads? n Two Ways to Obtain a New Thread n The Lifecycle of a Thread n Four Kinds of Thread.
Concurrency Control 1 Fall 2014 CS7020: Game Design and Development.
Threads. Objectives You must be able to answer the following questions –What code does a thread execute? –What states can a thread be in? –How does a.
1 Dr.A.Srinivas PES Institute of Technology Bangalore, India
Comunication&Synchronization threads 1 Programación Concurrente Benemérita Universidad Autónoma de Puebla Facultad de Ciencias de la Computación Comunicación.
Threads in Java Threads Introduction: After completing this chapter, you will be able to code your own thread, control them efficiently without.
Thread A thread represents an independent module of an application that can be concurrently execution With other modules of the application. MULTITHREADING.
Peyman Dodangeh Sharif University of Technology Fall 2014.
Multithreading and Garbage Collection Session 16.
Java Threads DBI – Representation and Management of Data on the Internet.
Multithreading. Multitasking The multitasking is the ability of single processor to perform more than one operation at the same time Once systems allowed.
Concurrency (Threads) Threads allow you to do tasks in parallel. In an unthreaded program, you code is executed procedurally from start to finish. In a.
Concurrency in Java MD. ANISUR RAHMAN. slide 2 Concurrency  Multiprogramming  Single processor runs several programs at the same time  Each program.
Tutorial 2: Homework 1 and Project 1
Multithreading The objectives of this chapter are:
Threads in Java Two ways to start a thread
Multithreading / Concurrency
Thread Pools (Worker Queues) cs
Multi Threading.
Thread Pools (Worker Queues) cs
Multithreaded Programming in Java
Threads Chate Patanothai.
Definitions Concurrent program – Program that executes multiple instructions at the same time. Process – An executing program (the running JVM for Java.
Advanced Programming Behnam Hatami Fall 2017.
Threads cs
Multithreading.
Multithreading.
برنامه‌نویسی چندنخی Multi-Thread Programming
Computer Science 2 06A-Java Multithreading
NETWORK PROGRAMMING CNET 441
Threads and Multithreading
Multithreading The objectives of this chapter are:
Java Chapter 3 (Estifanos Tilahun Mihret--Tech with Estif)
Presentation transcript:

Java Threads

Introduction

Process 1 Processes and Threads Environment Stack Code Heap CPU State Process 2 Environment Stack Code Heap CPU State

Process 1 Environment Code Heap Stack CPU State Thread 2 Stack CPU State Thread 1 Stack CPU State Thread 3 Processes and Threads

Terminology A thread is a single sequence of execution within a program Multiprogramming: -Running multiple processes concurrently Multithreading: -Running multiple threads within one process concurrently -That is, having several code executions within a single process Concurrency is achieved either by using several processors or by time-slicing over one processor

Time Slicing vs. Parallelism CPUCPU1CPU2

Multiple Threads in an Application Each thread has its own run-time stack and CPU state (i.e., register content, next instruction, etc. ) If two threads execute the same method, each will have its own copy of the local variables the methods uses However, all threads see the same dynamic memory, i.e., heap -which variables are stored on the heap? Two different threads can act on the same object and same static fields concurrently

Why Threads? Improve the responsiveness of applications -i.e., users wait less time Improve utilization of resources -e.g., one thread can run while the other waits for I/O Provide a convenient programming technique -run resource cleaners in the background -graphical applications -monitor resource status

Java Threads

Class Thread We use the class Thread in order to create and run threads Two ways to create Thread objects: -Implementing Runnable and wrapping with Thread -Extending Thread Thread itself also implements Runnable, so in both ways you implement the method run()

Implementing Runnable public class MinusPrinter implements Runnable { public void run() { for(int i=0; i<1000; ++i) { System.out.print("-"); } Runnable r = new MinusPrinter(); Thread t1 = new Thread(r);

Extending Thread public class PlusPrinter extends Thread { public void run() { for(int i=0; i<1000; ++i) { System.out.print("+"); } Thread t2 = new PlusPrinter();

Running Threads A Thread's execution starts by invoking its method start() This method invokes its method run() in a new thread public static void main(String argv[]) { Runnable r = new MinusPrinter(); Thread t1 = new Thread(r); Thread t2 = new PlusPrinter(); t1.start(); t2.start(); }

The Output

Java Thread Scheduling

Thread Scheduling Usually, threads run one at a time -Unless several processors are being used Thread execution is merged in order to provide concurrency

Scheduling Threads I/O operation completes start() Currently executed thread Ready queue Waiting for I/O operation to be completed Waiting to be notified Sleeping Waiting to enter a synchronized section Newly created threads Blocked queue

Alive Thread State Diagram New ThreadDead Thread Running Runnable new PlusPrinter(); run() method returns for (…) { … } Blocked Object.wait() Thread.sleep() blocking IO call waiting on a monitor thread.start();

Thread Scheduling Thread scheduling is the mechanism used to determine how Runnable threads (in the ready queue) are allocated CPU time Java's scheduling is based on priorities Each thread has a priority - an integer number -Use thread.getPriority() / setPriority() to control priorities In principle, the runtime system chooses the thread that has the highest priority

Thread Scheduling (cont) If several threads have the same priority, an arbitrary one is chosen Scheduling may violate the priority-based policy to avoid starvation of low-priority threads Java's scheduling also uses time slicing, when it is supported by the operating system -mainly used for sharing CPU among equal highest-priority threads

Thread Scheduling (cont) A thread runs until one of the following occurs: The thread dies (e.g., run() completes) The thread becomes not Runnable (e.g., sleeps or waits for an IO operation to complete) A higher-priority thread becomes Runnable On systems that support time-slicing, its time allotment has expired The thread yields (discussed later)

Scheduling is OS Dependant! Java maps Java threads to OS threads In particular, Java relies on the operating system for -Time slicing -Priorities Thus, scheduling differs from one system to another Do not count on scheduling and priorities for algorithm correctness!

Relinquishing the CPU A running thread can explicitly relinquish the CPU for other threads to use The static method Thread.yield() temporarily pauses the currently executing thread and allows other threads to execute A thread can block for a while using the method thread.sleep(milliseconds)

Changing the Old Example public class MinusPrinter implements Runnable { public void run() { for(int i=0; i<1000; ++i) { System.out.print("-"); Thread.yield(); } public class PlusPrinter extends Thread { public void run() { for(int i=0; i<1000; ++i) { System.out.print("+"); Thread.yield(); }

The Output

Daemon Threads There are two types of threads: -daemon threads (like the garbage-collection thread) -non-daemon threads (like the thread running main() ) JVM will let all non-daemon threads complete (i.e., complete the execution of run() ) When only daemon threads stay alive, they are killed and JVM exits Controlled by thread.isDaemon and thread.setDeamon

Notes Threads inherit their priority and daemon properties from their creating threads The method thread.join() blocks and waits until the thread completes running A thread can have a name for identification Stopping a running thread was possible in old versions of Java, but it is now deprecated -Instead, interruption mechanisms should be used

Garbage Collection The garbage collector of Java runs on a separate (daemon) thread An object is a candidate for garbage collection if this object can no longer be accessed by any living thread

Synchronizing Threads

Thread Synchronization Consider the following consumer-producer scenario:

The Simpson Simulation public class CookieJar { int contents; boolean hasCookie = false; public void putCookie(String who, int value) { while (hasCookie) {} contents = value; hasCookie = true; System.out.println(who + " put cookie " + value); } public int getCookie(String who) { while (!hasCookie) {} hasCookie = false; System.out.println(who + " got cookie " + contents); return contents; }} horribly inefficient!! try {Thread.sleep(1000);} catch (InterruptedException e) {}

The Simpson Simulation (cont) public class Homer implements Runnable { CookieJar jar; public Homer(CookieJar jar) { this.jar = jar; } public void eat() { int cookie = jar.getCookie("Homer"); } public void run() { for (int i = 1 ; i <= 10 ; i++) eat(); }

The Simpson Simulation (cont) public class Marge implements Runnable { CookieJar jar; public Marge(CookieJar jar) { this.jar = jar; } public void bake(int cookie) { jar.putCookie("Marge", cookie); } public void run() { for (int i = 0 ; i < 10 ; i++) bake(i); }

The Simpson Simulation (cont) public class RunSimpsons { public static void main(String[] args) { CookieJar jar = new CookieJar(); Homer homer = new Homer(jar); Marge marge = new Marge(jar); new Thread(homer).start(); new Thread(marge).start(); }

Oops! Missed a Cookie! public class CookieJar { int contents; boolean hasCookie = false; public void putCookie(String who, int value) { while (hasCookie) { sleep(); } contents = value; hasCookie = true; } public int getCookie(String who) { while (!hasCookie) { sleep();} hasCookie = false; return contents; }} Homer Marge

Race Condition Example Put green piecesPut red pieces How can we have alternating colors?

Race Condition Race condition – -Two threads are simultaneously reading or modifying some shared data -The outcome of a program is affected by the order in which the program's threads are allocated CPU time Both threads “race” for accessing shared data When undesired, synchronization is required

Monitors and Locks Monitors are key elements in Java's thread synchronization Every object has a monitor An object's monitor is used as a guardian that watches a block of code (called a critical section) and enables only one thread to enter that code To enter a critical section, a thread must first acquire an ownership over the corresponding monitor

Unique Lock Ownerships Only one thread can own a specific monitor If a thread A tries to enter a block under a monitor and a different thread B has already entered that block, A will wait until B releases the monitor and (hopefully) that monitor will be passed to A -Hence, monitors are related to as locks When a thread leaves the critical section, the monitor is automatically released Threads awaiting a monitor are blocked and queued

The synchronized keyword To monitor a block code using the monitor of Object o, use the synchronized keyword as follows: synchronized(o) { critical-section } synchronized method() {critical-section} is a shorthand for method() {synchronized(this) {critical-section} } –

An Example public class BankAccount { private float balance; public synchronized void deposit(float amount) { balance += amount; } public synchronized void withdraw(float amount) { balance -= amount; } public synchronized void transfer (float amount, BankAccount target) { withdraw(amount); target.deposit(amount); }}

Critical Sections Bank Account deposit() t1t2t3

Synchronization Scopes private String a = "hello"; private Date b = new Date(); void a() { synchronized(a) { System.out.println("In A 1"); System.out.println("In A 2"); } void b() { synchronized(b) { System.out.println("In B 1"); System.out.println("In B 2"); } synchronized void a() { System.out.println("In A 1"); System.out.println("In A 2"); } synchronized void b() { System.out.println("In B 1"); System.out.println("In B 2"); }

Synchronization Scopes static String c = "world"; void a() { synchronized (c) { System.out.println("In A 1"); System.out.println("In A 2"); } void b() { synchronized (getClass()) { System.out.println("In B 1"); System.out.println("In B 2"); } static synchronized void a() { System.out.println("In A 1"); System.out.println("In A 2"); } static synchronized void b() { System.out.println("In B 1"); System.out.println("In B 2"); } Uses the monitor of the Class object

Synchronization Scopes What will happen here? void a() { Date d = new Date(); synchronized (d) { System.out.println("In A 1"); System.out.println("In A 2"); }

Back to the Simpsons public synchronized void putCookie(String who, int value) { while (hasCookie) { sleep(); } contents = value; hasCookie = true; } public synchronized int getCookie(String who) { while (!hasCookie) { sleep(); } hasCookie = false; return contents; } Homer Marge deadlock!

Another Deadlock Example public class BankAccount { private float balance; public synchronized void deposit(float amount) { balance += amount; } public synchronized void withdraw(float amount) { balance -= amount; } public synchronized void transfer (float amount, BankAccount target) { withdraw(amount); target.deposit(amount); }}

Deadlocks deposit() Alice's Account Bob's Account t1t2 deposit() ? transfer() withdraw() transfer() withdraw()

wait() and notify() Suppose that an object has some monitor, but conditions disable it from completing the critical section The wait/notify mechanism enables that object to release the monitor and wait until conditions are changed

wait() The method Object.wait() requires the current thread to own the monitor of the object When called, the current thread -releases ownership on the object's monitor -stops and waits until some other thread will wake it up and the monitor will be re-obtained

notify() Like wait, requires the object to own the monitor The method Object.notify() wakes up an arbitrary thread that waits on the monitor of the object Object.notifyAll() wakes all such threads When a thread is waken up, it regularly waits for the monitor to be available The thread calling notify should release the monitor for the waiting thread to continue

Waiting and Notifying synchronized (lock) { while (!resourceAvailable()) { lock.wait(); } cosumeResource(); } produceResource(); synchronized (lock) { lock.notifyAll(); }

Wait/Notify Sequence Lock Object Consumer Thread Producer Thread 1. synchronized(lock){ 2. lock.wait(); 3. produceResource() 4. synchronized(lock) { 5. lock.notify(); 6.} 7. Reacquire lock 8.Return from wait() 9. consumeResource(); 10. }

Wait/Notify Sequence Lock Object Consumer Thread Producer Thread 1. synchronized(lock){ 2. lock.wait(); 3. produceResource() 4. synchronized(lock) { 5. lock.notify(); 6.} 7. Reacquire lock 8. Return from wait() 9. consumeResource(); 10. }

Wait/Notify Sequence Lock Object Consumer Thread Producer Thread 1. synchronized(lock){ 2. lock.wait(); 3. produceResource() 4. synchronized(lock) { 5. lock.notify(); 6.} 7. Reacquire lock 8. Return from wait() 9. consumeResource(); 10. }

Wait/Notify Sequence Lock Object Consumer Thread Producer Thread 1. synchronized(lock){ 2. lock.wait(); 3. produceResource() 4. synchronized(lock) { 5. lock.notify(); 6.} 7. Reacquire lock 8. Return from wait() 9. consumeResource(); 10. }

Wait/Notify Sequence Lock Object Consumer Thread Producer Thread 1. synchronized(lock){ 2. lock.wait(); 3. produceResource() 4. synchronized(lock) { 5. lock.notify(); 6.} 7. Reacquire lock 8. Return from wait() 9. consumeResource(); 10. }

Wait/Notify Sequence Lock Object Consumer Thread Producer Thread 1. synchronized(lock){ 2. lock.wait(); 3. produceResource() 4. synchronized(lock) { 5. lock.notify(); 6.} 7. Reacquire lock 8. Return from wait() 9. consumeResource(); 10. }

Wait/Notify Sequence Lock Object Consumer Thread Producer Thread 1. synchronized(lock){ 2. lock.wait(); 3. produceResource() 4. synchronized(lock) { 5. lock.notify(); 6.} 7. Reacquire lock 8. Return from wait() 9. consumeResource(); 10. }

Wait/Notify Sequence Lock Object Consumer Thread Producer Thread 1. synchronized(lock){ 2. lock.wait(); 3. produceResource() 4. synchronized(lock) { 5. lock.notify(); 6.} 7. Reacquire lock 8. Return from wait() 9. consumeResource(); 10. }

Wait/Notify Sequence Lock Object Consumer Thread Producer Thread 1. synchronized(lock){ 2. lock.wait(); 3. produceResource() 4. synchronized(lock) { 5. lock.notify(); 6.} 7. Reacquire lock 8. Return from wait() 9. consumeResource(); 10. }

Wait/Notify Sequence Lock Object Consumer Thread Producer Thread 1. synchronized(lock){ 2. lock.wait(); 3. produceResource() 4. synchronized(lock) { 5. lock.notify(); 6.} 7. Reacquire lock 8. Return from wait() 9. consumeResource(); 10. }

Wait/Notify Sequence Lock Object Consumer Thread Producer Thread 1. synchronized(lock){ 2. lock.wait(); 3. produceResource() 4. synchronized(lock) { 5. lock.notify(); 6.} 7. Reacquire lock 8. Return from wait() 9. consumeResource(); 10. }

Fixed Simpson Example public synchronized void putCookie(String who, int value) { while (hasCookie) { try { wait(); } catch(InterruptedException e){} } contents = value; hasCookie = true; System.out.println(who + " put cookie " + value); notifyAll(); } public synchronized int getCookie(String who) { while (!hasCookie) { try{ wait(); } catch(InterruptedException e){} } hasCookie = false; System.out.println(who + " got cookie " + contents); notifyAll(); return contents; } Homer Marge

Multithreading Client- Server

Server Client Request Handler Client Request Handler …

Multithreading Client-Server When a new request arrives, it is served in a new thread The server thread continues to listen Next, we will show how the EchoServer example of last week should be fixed to handle concurrent requests

Server import java.net.*; import java.io.*; public class EchoServer { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(8000); while (true) { try { Socket socket = serverSocket.accept(); new EchoRequestHandler(socket).start(); } catch (Exception e) { System.err.println("Error: " + e.getMessage()); }}}}

Request Handler public class EchoRequestHandler extends Thread { Socket socket = null; public EchoRequestHandler(Socket socket) { this.socket = socket; } public void run() {... next slide... } }

Request Handler public void run() { try { BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintStream writer = new PrintStream(socket.getOutputStream()); String lineRead = null; while ((lineRead = reader.readLine()) != null) { writer.println("You wrote: " + lineRead); writer.flush(); } } catch (IOException exp) { System.err.println("Error: " + exp.getMessage());} finally { try { if (!socket.isClosed()) socket.close(); } }}

Thread Pools

Why Thread Pools? Thread pools improve resource utilization -The overhead of creating a new thread is significant Thread pools enable applications to control and bound their thread usage -Creating too many threads in one JVM can cause the system to run out of memory and even crash

Thread Pools in Servers Thread pools are especially important in client-server applications -The processing of each individual task is short-lived and the number of requests is large -Servers should not spend more time and consume more system resources creating and destroying threads than processing actual user requests When too many requests arrive, thread pools enable the server to force clients to wait threads are available

The “Obvious” Implementation There is a pool of threads Each task asks for a thread when starting and returns the thread to the pool after finishing When there are no available threads in the pool the thread that initiates the task waits till the pool is not empty What is the problem here?

The “Obvious” Implementation is Problematic When the pool is empty, the submitting thread has to wait for a thread to be available -We usually want to avoid blocking that thread -A server may want to perform some actions when too many requests arrive Technically, Java threads that finished running cannot run again

Task Queue Worker Threads wait() Q is Empty All the worker threads wait for tasks A Possible Solution

Task Queue Worker Threads Task The number of worker threads is fixed. When a task is inserted to the queue, notify is called. A Possible Solution

Task Queue Worker Threads notify() The number of worker threads is fixed. When a task is inserted to the queue, notify is called. A Possible Solution

Task Queue Worker Threads The task is executed by the tread A Possible Solution

Task Queue Worker Threads The task is executed by the tread Task notify() A Possible Solution

Task Queue Worker Threads The remaining tasks are executed by the tread A Possible Solution

Task Queue Worker Threads When a task ends the tread is released While the Q is not empty, take the task from the Q and run it (if the Q was empty, wait() would have been called) A Possible Solution

Task Queue Worker Threads A new task is executed by the released tread A Possible Solution

Thread Pool Implementation public class TaskManager { LinkedList taskQueue = new LinkedList(); List threads = new LinkedList(); public TaskManager(int numThreads) { for(int i=0; i<numThreads; ++i) { Thread worker = new Worker(taskQueue); threads.add(worker); worker.start(); }} public void execute(Runnable task) { synchronized(taskQueue) { taskQueue.addLast(task); taskQueue.notify(); } } }

Thread Pool Implementation public class Worker extends Thread { LinkedList taskQueue = null; public Worker(LinkedList queue) { taskQueue = queue; } public void run() { Runnable task = null; while (true) { synchronized (taskQueue) { while (taskQueue.isEmpty()) { try {taskQueue.wait();} catch (InterruptedException ignored) {}} task = (Runnable) taskQueue.removeFirst(); } task.run(); }}}

Risks in Using Thread Pools Threads can leak -A thread can endlessly wait for an I/O operation to complete -For example, the client may stop the interaction with the socket without closing it properly -What if task.run() throws a runtime exception? Solutions: -Bound I/O operations by timeouts -Catch possible runtime exceptions

Pool Size Each thread consumes resources -memory, management overhead, etc. Therefore, you have to Tune the thread pool size according to the number and characterizations of expected tasks There should also be a limit on the size of the task queue -What should we do when too many requests arrive?