Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
12 views

Advanced Java Programming Tithreading

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views

Advanced Java Programming Tithreading

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 36

Java Multithreading

By Abdo A.

1
Multithreading
 The objectives of this chapter are:
 To understand the purpose of multithreading

 To describe Java's multithreading mechanism

 To explain concurrency issues caused by multithreading

 To outline synchronized access to shared resources

VM - virtual machine
OS - operating System
GUI - graphical user interface
2
Introduction
 The unit of resource ownership is referred to as a process or task
 The unit of dispatching is referred to as a thread or lightweight process
 One or More Threads in a Process
 In an OS that supports threads, scheduling and dispatching is done on a
thread basis
 Most of the state information dealing with execution is maintained in
thread-level data structures
 suspending a process involves suspending all threads of the process

 termination of a process terminates all threads within the process

3
Threads and Processes

4
Threads vs. processes
 Threads differ from traditional multitasking operating system processes
in that:
 processes are typically independent, while threads exist as subsets of a

process
 processes carry considerably more state information than threads,

whereas multiple threads within a process share process state as well


as memory and other resources
 processes have separate address spaces, whereas threads share their

address space
 processes interact only through system-provided inter-process

communication mechanisms
 context switching between threads in the same process is typically

faster than context switching between processes.


 Process creation is heavy-weight while thread creation is light-weight 5
Benefits of Threads

Less time to Threads enhance


terminate a Switching efficiency in
thread than a between two communication
Takes less process between programs
time to threads takes less
create a new time than
thread than switching
a process between
processes

6
What is Multithreading?
 A multi-processing Operating System can run several
processes at the same time
 Each process has its own address/memory space

 The OS's scheduler decides when each process is executed

 Only one process is actually executing at any given time.


However, the system appears to be running several
programs simultaneously
 Separate processes to not have access to each other's
memory space
 Many OSes have a shared memory system so that processes
can share memory space
 Multithreading is similar to multi-processing.
 In a multithreaded application, there are several points of
execution within the same memory space.
• Each point of execution is called a thread
• Threads share access to memory 7
Why use Multithreading?
 In a single threaded application, one thread of execution must
do everything
 If an application has several tasks to perform, those tasks will be
performed when the thread can get to them.
 A single task which requires a lot of processing can make the

entire application appear to be "sluggish" or unresponsive.


 In a multithreaded application, each task can be performed by a
separate thread
 If one thread is executing a long process, it does not make the entire
application wait for it to finish.
 If a multithreaded application is being executed on a system that has
multiple processors, the OS may execute separate threads
simultaneously on separate processors.
8
Multithreading vs. Single threading
 Single threading: when the OS does not recognize the
concept of thread.
 Multithreading: when the OS supports multiple threads of
execution within a single process.
 MS-DOS supports a single user process and a single thread.
 Older UNIXs supports multiple user processes but only
support one thread per process.
 Solaris and Windows NT support multiple threads.

9
Multithreading vs. Single threading

10
multiple threads and multiprocessor

multiple threads within the same process can execute in parallel


on a multiprocessor

11
Why do we need threads?
 Responsiveness – enhance parallel processing and utilize
the idle time of the CPU
 Resource Sharing – threads share resources of process,
easier than shared memory or message passing
 Economy – cheaper than process creation, thread switching
lower overhead than context switching
 Scalability – process can take advantage of multiprocessor
architectures
 Prioritize your work depending on priority

12
Example

 Threads of execution
 Each thread is a portion of a program that can execute

concurrently with other threads (multithreading)


Example: downloading a video clip
 Instead of having to download the entire clip then play it:
 Download a portion, play that portion, download the next
portion, play that portion... (streaming)
 Ensure that it is done smoothly

13
What Kind of Applications Use
Multithreading?
 Any kind of application which has distinct tasks which can be
performed independently
 Any application with a GUI.
Threads dedicated to the GUI can delegate the processing of user requests to
other threads.
The GUI remains responsive to the user even when the user's requests are
being processed
 Any application which requires asynchronous response
 Network based applications are ideally suited to multithreading.
 Data can arrive from the network at any time.
 In a single threaded system, data is queued until the thread can read the data
 In a multithreaded system, a thread can be dedicated to listening for data on
the network port. When data arrives, the thread reads it immediately and
processes it or delegates its processing to another thread 14
Example
 Consider a simple web server
The web server listens for request and serves it
If the web server was not multithreaded, the requests
processing would be in a queue, thus increasing the
response time and also might hang the server if there
was a bad request.
By implementing in a multithreaded environment, the
web server can serve multiple request simultaneously
thus improving response time

15
How does it all work?
Each thread is given its own "context"
 A thread's context includes virtual registers and its own calling stack
The "scheduler" decides which thread executes at any given time
 The VM may use its own scheduler
 Since many OSes now directly support multithreading, the
VM may use the system's scheduler for scheduling threads
The scheduler maintains a list of ready threads (the run queue)
and a list of threads waiting for input (the wait queue)
Each thread has a priority. The scheduler typically schedules
between the highest priority threads in the run queue
 Note: the programmer cannot make assumptions about how
threads are going to be scheduled. Typically, threads will be
executed differently on different platforms. 16
Thread Support in Java
Few programming languages directly support threading
 Although many have add-on thread support
 Add on thread support is often quite cumbersome to use
The Java Virtual machine has its own runtime threads
 Used for garbage collection
Threads are represented by a Thread class
 A thread object maintains the state of the thread
 It provides control methods such as interrupt, start, sleep, yield, wait
When an application executes, the main method is executed by a
single thread.
 If the application requires more threads, the application must
create them.
17
Thread Support in Java
 Applications are typically divided into processes during the
design phase, and a master process explicitly contains sub
processes and a single process may contain multiple threads
 All threads within a process share the same state and same
memory space, and can communicate with each other
directly, because they share the same variables.
 Threads are object in java language.
 They can be created by using two different mechanisms.
 By extending thread class or by implementing
Runnable interface.

18
Life cycle of a Thread (Thread States)
1. New If you create an instance of Thread
class but before the invocation of start() method.
2. Runnable After invocation of start() method,
but the thread scheduler has not selected it to be
the running thread.
3. Running if the thread scheduler has selected
it. System assigns processor to thread (thread
begins executing) When run completes or
terminates, enters dead state
4. Non-Runnable Still alive, but is currently
not eligible to run.
i. Waiting − Sometimes, a thread transitions to
the waiting state while the thread waits for
another thread to perform a task.
ii. Timed Waiting/sleeping, suspend()
an I/O operation
5. Terminated
dead state when its run() method exits.
19
Life cycle of a Thread (Thread States)

20
Other Thread States
 Blocked state
 Entered from running state
 Blocked thread cannot use processor, even if available
 Common reason for blocked state - waiting on I/O request
 Sleeping state
 Entered when sleep method called
 Cannot use processor
 Enters ready state after sleep time expires
 Waiting state
 Entered when wait called in an object thread is accessing
 One waiting thread becomes ready when object calls notify
 notifyAll - all waiting threads become ready
21
Thread Methods
 static void sleep( long milliseconds )
 Thread sleeps (does not contend for processor) for number of
milliseconds
 Why might we want a program to invoke sleep?

 Can give lower priority threads a chance to run

 void interrupt() - interrupts a thread


 boolean isInterrupted()
 Determines if a thread is interrupted

 boolean isAlive()
 Returns true if start called and thread not dead (run has not
completed)
 getPriority() - returns this thread's priority
 setPriority() – sets this threads priority
 Etc. 22
A. Extending the Thread Class
 The steps for creating a thread are:
1. Create a class by extending the Thread class and
override the run() method:
public class MyThread extends Thread {
public void run(){
System.out.println("this is the thread to be executed");
}
}
2. Create a thread object:
MyThread thr1 = new MyThread();
3. Start Execution of created thread:
thr1.start(); 23
Implementing the Runnable Interface
1. Create a class that implements the interface Runnable and override
run() method:
2. Create an Object of the class which implement the Runnable interface
3. Creating a generic Thread Object and pass the object created in step 2 as
a parameter
4. Start Execution: call the start method using the generic thread object
public class MyThread implements Runnable { //step 1
public void run(){
System.out.println("this is the thread to be executed"); } }
class ThreadEx1 {
public static void main(String [] args ) {
MyThread th=new MyThread (); //step-2
Thread t = new Thread(th); //step -3
t.start(); //step -4 }} 24
Thread Class vs Runnable Interface
 It is a little confusing why there are two ways of doing the
same thing in the threading API. It is important to understand
the implication of using these two different approaches.
 By extending the thread class, the derived class itself is a

gains full control over the thread life cycle.


 Runnable interface does not give developers any control over the

thread itself, as it simply defines the unit of work that will


be executed in a thread.
 Another important point is that when extending the Thread

class, the derived class cannot extend any other base.


 By implementing the Runnable interface, the class can still

extend other base classes if necessary. 25


Thread Class vs Runnable Interface
 To summarize, if the program needs a full control over the
thread life cycle, extending the Thread class is a good
choice, and
 If the program needs more flexibility of extending other
base classes, implementing the Runnable interface would
be preferable. If none of these is present, either of them is
fine to use

26
Properly Terminating Threads
In Java 1.1, the Thread class had a stop() method
 One thread could terminate another by invoking its stop()
method.
 However, using stop() could lead to deadlocks
 The stop() method is now deprecated. DO NOT use the
stop method to terminate a thread
 The correct way to stop a thread is to have the run method
terminate
 Add a boolean variable which indicates whether the
thread should continue or not
 Provide a set method for that variable which can be
invoked by another thread
27
Creating Multiple Threads
 The previous example illustrates a Runnable class which creates
its own thread when the start method is invoked.
 If one wished to create multiple threads, one could simple create
multiple instances of the Runnable class and send each object a
start message
 Each instance would create its own thread object
 Is the a maximum number of threads which can be created?
 There is no defined maximum in Java.
 If the VM is delegating threads to the OS, then this is platform
dependent.
 A good rule of thumb for maximum thread count is to allow 2Mb
of ram for each thread
 Although threads share the same memory space, this can be a
reasonable estimate of how many threads your machine can handle. 28
Thread Priorities
Every thread is assigned a priority (between 1 and 10)
The default is 5, and the higher the number, the higher the priority
Can be set with setPriority(int aPriority)
The standard mode of operation is that the scheduler executes threads
with higher priorities first.
This simple scheduling algorithm can cause problems. Specifically, one
high priority thread can become a "CPU hog".
A thread using vast amounts of CPU can share CPU time with other
threads by invoking the yield() method on itself.
Most OSes do not employ a scheduling algorithm as simple as this one
Most modern OSes have thread aging
o The more CPU a thread receives, the lower its priority becomes
o The more a thread waits for the CPU, the higher its priority becomes
o Because of thread aging, the effect of setting a thread's priority is
dependent on the platform 29
Yield() and Sleep()
Sometimes a thread can determine that it has nothing to do
 Sometimes the system can determine this. ie. waiting for I/O
When a thread has nothing to do, it should not use CPU
This is called a busy-wait.
Threads in busy-wait are busy using up the CPU doing nothing.
 Often, threads in busy-wait are continually checking a flag to see if there is anything to do.
It is worthwhile to run a CPU monitor program on your desktop
You can see that a thread is in busy-wait when the CPU monitor goes up
(usually to 100%), but the application doesn't seem to be doing anything.
Threads in busy-wait should be moved from the Run queue to the Wait queue
so that they do not monopolize the CPU
 Use yield() or sleep(time)
 Yield simply tells the scheduler to schedule another thread
 Sleep guarantees that this thread will remain in the wait queue for the specified number of
milliseconds.
30
Concurrent Access to Data
 Those familiar with databases will understand that concurrent access to
data can lead to data integrity problems
Specifically, if two sources attempt to update the same data at the
same time, the result of the data can be undefined.
The outcome is determined by how the scheduler schedules the two
sources. Since the schedulers activities cannot be predicted, the
outcome cannot be predicted
 Databases deal with this mechanism through "locking"
 If a source is going to update a table or record, it can lock the table or
record until such time that the data has been successfully updated.
 While locked, all access is blocked except to the source which holds
the lock.
 Java has the equivalent mechanism. It is called synchronization
 Java has a keyword called synchronized
31
Synchronization
 In Java, every object has a lock
 To obtain the lock, you must synchronize with the object

 The simplest way to use synchronization is by declaring one or


more methods to be synchronized
When a synchronized method is invoked, the calling thread attempts
to obtain the lock on the object.
if it cannot obtain the lock, the thread goes to sleep until the lock
becomes available
Once the lock is obtained, no other thread can obtain the lock until it
is released. i.e, the synchronized method terminates
When a thread is within a synchronized method, it knows that no
other synchronized method can be invoked by any other thread
Therefore, it is within synchronized methods that critical data is
updated 32
Providing Thread Safe Access to Data
 If an object contains data which may be updated from
multiple thread sources, the object should be implemented
in a thread-safe manner
All access to critical data should only be provided through
synchronized methods (or synchronized blocks).
In this way, we are guaranteed that the data will be updated by only
one thread at a time.
public class SavingsAccount {
private float balance;
public synchronized void withdraw(float anAmount){
if ((anAmount>0.0) && (anAmount<=balance))
balance = balance - anAmount;
}

public synchronized void deposit(float anAmount) {


if (anAmount>0.0)
balance = balance + anAmount;
} 33
Thread Safety Performance Issues
However, there is an overhead associated with synchronization
 Many threads may be waiting to gain access to one of the object's
synchronized methods
 The object remains locked as long as a thread is within a synchronized
method.
 Ideally, the method should be kept as short as possible.
Another solution is to provide synchronization on a block of
code instead of the entire method
 In this case, the object's lock is only held for the time that the thread is
within the block.
 The intent is that we only lock the region of code which requires access to
the critical data. Any other code within the method can occur without the lock.
 In high load situations where multiple threads are attempting to access
critical data, this is by far a much better implementation.
34
Block Synchronization
public class SavingsAccount {
private float balance;
public void withdraw(float anAmount) {
if (anAmount<0.0)
throw new IllegalArgumentException("Withdraw amount
negative");
synchronized(this) {
if (anAmount<=balance)
balance = balance - anAmount;
}
}
public void deposit(float anAmount) {
if (anAmount<0.0)
throw new IllegalArgumentException("Deposit amount
negative");
synchronized(this)
{
balance = balance + anAmount;
}} 35
The end

Thank you!

36

You might also like