0% found this document useful (0 votes)
91 views

Chapter 11

- Java provides built-in support for multithreaded programming where a program contains multiple parts that can run concurrently as separate execution threads. - There are two types of multitasking - process-based allows running multiple programs at once, while thread-based allows a single program to perform multiple tasks simultaneously. - Threads in Java exist in different states and priorities, and synchronization techniques like monitors and synchronized methods are used to prevent conflicts when threads access shared resources.

Uploaded by

gehaf92842
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
91 views

Chapter 11

- Java provides built-in support for multithreaded programming where a program contains multiple parts that can run concurrently as separate execution threads. - There are two types of multitasking - process-based allows running multiple programs at once, while thread-based allows a single program to perform multiple tasks simultaneously. - Threads in Java exist in different states and priorities, and synchronization techniques like monitors and synchronized methods are used to prevent conflicts when threads access shared resources.

Uploaded by

gehaf92842
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 39

Chapter 11

Multithreaded Programming
Introduction:

• Unlike many other computer languages, Java provides built-in support for multithreaded
programming.
• A multithreaded program contains two or more parts that can run concurrently.
• Each part of such a program is called a thread, and each thread defines a separate path of
execution.
• Multithreading is a specialized form of multitasking.
• There are two distinct types of multitasking: process based and thread-based.
• process-based multitasking is the feature that allows your computer to run two or more
programs concurrently. For example, process-based multitasking enables you to run the
Java compiler at the same time that you are using a text editor
• In a thread-based multitasking environment, the thread is the smallest unit of
dispatchable code. This means that a single program can perform two or more tasks
simultaneously. For instance, a text editor can format text at the same time that it is
printing, these two actions are being performed by two separate threads.
The Java Thread Model:

• Threads exist in several states.


• A thread can be running.
• It can be ready to run as soon as it gets CPU time.
• A running thread can be suspended, which temporarily suspends its activity.
• A suspended thread can then be resumed, allowing it to pick up where it left off.
• A thread can be blocked when waiting for a resource.
• At any time, a thread can be terminated, which halts its execution immediately.
• Once terminated, a thread cannot be resumed.

Thread Priorities:

• A thread can voluntarily relinquish control. This is done by explicitly yielding, sleeping,
or blocking on pending I/O. In this scenario, all other threads are examined, and the
highest-priority thread that is ready to run is given the CPU.
• A thread can be preempted by a higher-priority thread. In this case, a lower-priority
thread that does not yield the processor is simply preempted—no matter what it is
doing— by a higher-priority thread. Basically, as soon as a higher-priority thread wants to
run, it does. This is called preemptive multitasking.

Synchronization:

• if you want two threads to communicate and share a complicated data structure, such as
a linked list, you need some way to ensure that they don’t conflict with each other. That
is, you must prevent one thread from writing data while another thread is in the middle of
reading it. For this purpose, Java implements an elegant twist on an age-old model of
interprocess synchronization: the monitor.
• The monitor is a control mechanism first defined by C.A.R. Hoare. You can think of a
monitor as a very small box that can hold only one thread. Once a thread enters a
monitor, all other threads must wait until that thread exits the monitor. In this way, a
monitor can be used to protect a shared asset from being manipulated by more than one
thread at a time.
Messaging:
Java’s messaging system allows a thread to enter a synchronized method on an object, and
then wait there until some other thread explicitly notifies it to come out.

The Thread Class and the Runnable Interface:


To create a new thread, your program will either extend Thread or implement the Runnable
interface.
The Thread class defines several methods that help manage threads.
The Main Thread:

• When a Java program starts up, one thread begins running immediately. This is usually
called the main thread of your program.
• It is the thread from which other “child” threads will be spawned.
• Often, it must be the last thread to finish execution because it performs various
shutdown actions.
• The main thread is created automatically when your program is started.
• It can be controlled through a Thread object. To do so, you must obtain a reference to it
by calling the method currentThread( ), which is a public static member of Thread.
• Its general form is shown here:
static Thread currentThread( )
• This method returns a reference to the thread in which it is called.
• Once you have a reference to the main thread, you can control it just like any other
thread.
Output:

Order: the name of the thread, its priority,


and the name of its group.
Creating a Thread:
you create a thread by instantiating an object of type Thread. Java defines two ways in which
this can be accomplished:
• You can implement the Runnable interface.
• You can extend the Thread class.

Implementing Runnable:
The easiest way to create a thread is to create a class that implements the Runnable interface.
Output:

Extending Thread:
The second way to create a thread is to create a new class that extends Thread, and then to
create an instance of that class.
Choosing an Approach:

classes should be extended only when they are being enhanced or modified in some way. So,
if you will not be overriding any of Thread’s other methods, it is probably best to implement
Runnable.

Creating Multiple Threads:

your program can spawn as many threads as it needs.


output from this program is shown here:
Using isAlive( ) and join( ):
final boolean isAlive( )
The isAlive( ) method returns true if the thread upon which it is called is still running. It
returns false otherwise.

final void join( ) throws InterruptedException


• This method waits until the thread on which it is called terminates.
• Additional forms of join( ) allow you to specify a maximum amount of time that you want
to wait for the specified thread to terminate.
output from this program is shown here:
Thread Priorities:

To set a thread’s priority, use the setPriority( ) method, which is a member of Thread.
This is its general form:
final void setPriority(int level)
• level specifies the new priority setting for the calling thread.
• The value of level must be within the range MIN_PRIORITY and MAX_PRIORITY.
• Currently, these values are 1 and 10, respectively.
• To return a thread to default priority, specify NORM_PRIORITY, which is currently 5.
• These priorities are defined as static final variables within Thread.

You can obtain the current priority setting by calling the getPriority( ) method of Thread,
shown here:
final int getPriority( )
output from this program is shown here:

Synchronization:

• When two or more threads need access to a shared resource, they need some way to
ensure that the resource will be used by only one thread at a time.
• The process by which this is achieved is called synchronization.
• Java provides unique, language-level support for it.
• Key to synchronization is the concept of the monitor (also called a semaphore).
• A monitor is an object that is used as a mutually exclusive lock, or mutex.
• Only one thread can own a monitor at a given time.
• When a thread acquires a lock, it is said to have entered the monitor.
• All other threads attempting to enter the locked monitor will be suspended until the first
• thread exits the monitor. These other threads are said to be waiting for the monitor.
• A thread that owns a monitor can reenter the same monitor if it so desires.

You can synchronize your code in either of two ways


1) Using Synchronized Methods
2) Using synchronized Statement

Using Synchronized Methods:


output from this program is shown here:
To fix the preceding program, you must serialize access to call( ). That is, you must restrict
its access to only one thread at a time. To do this, you simply need to precede call( )’s
definition with the keyword synchronized,

This prevents other threads from entering call( ) while another thread is using it. After
synchronized has been added to call( ), the output of the program is as follows:

The synchronized Statement:

• Imagine that you want to synchronize access to objects of a class that was not designed
for multithreaded access. That is, the class does not use synchronized methods.
• Further, this class was not created by you, but by a third party, and you do not have access
to the source code. Thus, you can’t add synchronized to the appropriate methods within
the class.
• How can access to an object of this class be synchronized?
• The solution to this problem is quite easy: You simply put calls to the methods defined by
this class inside a synchronized block.
Interthread Communication:

• wait( ) tells the calling thread to give up the monitor and go to sleep until some other
thread enters the same monitor and calls notify( ).
• notify( ) wakes up a thread that called wait( ) on the same object.
• notifyAll( ) wakes up all the threads that called wait( ) on the same object. One of
the threads will be granted access.

These methods are declared within Object, as shown here:


final void wait( ) throws InterruptedException
final void notify( )
final void notifyAll( )
Additional forms of wait( ) exist that allow you to specify a period of time to wait.
output from this program is shown here:
output from this program is shown here:
Deadlock:
deadlock, which occurs when two threads have a circular dependency on a pair of
synchronized objects
output from this program is shown here:
Suspending, Resuming, and Stopping Threads:
Suspending, Resuming, and Stopping Threads Using Java 1.1 and Earlier:
Prior to Java 2, a program used suspend( ) and resume( ), which are methods defined by
Thread, to pause and restart the execution of a thread. They have the form shown below:
final void suspend( )
final void resume( )
Sample output from this program is shown here. (Your output may differ based on processor
speed and task load.)
The Thread class also defines a method called stop( ) that stops a thread. Its signature is
shown here:
final void stop( )
Once a thread has been stopped, it cannot be restarted using resume( ).

The Modern Way of Suspending, Resuming, and Stopping Threads:

While the suspend( ), resume( ), and stop( ) methods defined by Thread seem to be a
perfectly reasonable and convenient approach to managing the execution of threads, they
must not be used for new Java programs, because these methods are deprecated by Java 2.
Using Multithreading:
• when you have two subsystems within a program that can execute concurrently, make them
individual threads.
• If you create too many threads, you can actually degrade the performance of your program
rather than enhance it.
• Some overhead is associated with context switching. If you create too many threads, more
CPU time will be spent changing contexts than executing your program!
Disclaimer
 These slides are not original and have been prepared from various
sources for teaching purpose.
Sources:
 Herbert Schildt, Java™: The Complete Reference
Thank You

You might also like