This document discusses multithreading in Java. It defines threads as lightweight processes that exist within a process and share its resources. The main thread is executed when a Java program begins. Additional threads can be created by implementing the Runnable interface or extending the Thread class. Synchronization is needed when threads access shared resources to prevent interference. Methods can be synchronized to allow only one thread to access them at a time. The wait(), notify(), and notifyAll() methods allow threads to communicate about locked resources. Deadlocks can occur when threads have a circular dependency on locks. The Java concurrency utilities provide additional tools for multithreaded programming.
5. Automatically
In current programming , there are two basic
units of execution:
Processes and Threads
In the Java programming language, concurrent
programming is mostly concerned with threads.
6. Automatically
A process is a self-contained execution environment. A
process generally has a complete, private set of basic run
time resources: in particular each process has its own
memory space.
Processes are often seen as synonymous with programs or
applications. However, what the user sees as single
application may in fact be a set of cooperating processes.
To facilitate communication between processes, most Oss
support Inter Process Communication (IPC) resources, such
as pipes and sockets. IPC is used not just for
communication between processes on the same system but
processes on different systems.
Most implementations of the Java Virtual Machine run as a
single process. A Java application can create additional
processes using a “ProcessBuilder” object. Multiprocess
application is beyond the scope of this lesson.
7. Automatically
Threads are sometimes called lightweight processes.
Both processes and threads provide an execution
environment, but creating a new thread requires fewer
resources than creating a new process.
Threads exist within a process – every process has at least
one. Threads share the process’s resources including
memory and open files. This makes for efficient but
potentially problematic communication.
Multithreaded execution is an essential feature of the Java
platform. Every application has at least one thread – or
several. If you count “system” threads that do things like
memory management and signal handling. But from the
application programmer’s point of view, you start with just
one thread, called the main thread. This Thread has the
ability to create additional threads, as well demonstrate in
the next section.
8. Automatically
Multiprocessing
Manu users’ processes are processed by a single
processor UNIX system running on single server
handles many users
Multitasking
Single user many processes being processed by a
single processor. For single user more than one
processes can run – Windows – Notepad, Calc ,
browser etc.
9. Automatically
Multiprocessing allows several activities to occur
concurrently:
Multitasking
Process-based
multitasking
Thread-based
multitasking
Word Doc example: Auto
save, spell checker, print,
format text, Game Example
: Game is highly threaded
application
Which allows
processes(programs) to
run concurrently
Ex: Notepad, Media
Player, and Games can run
concurrently on Computer
Which allows part of the same
program to run concurrently,
means single process, having
multiple paths of execution –
called Multithreading
10. Each process have process ID, separate memory
space.
Every thread in a Java created and controlled by
a unique object of the class.
Java.lang.Thread class
Java provides thread based multitasking and
provides high level of facilities for multithreaded
programming.
11. Better resource utilization
Simpler Program Design
More responsive programs
Threads share same address space
Context-switching between threads is usually
less expensive than context-switching between
processes
The cost of communication between threads is
relatively low.
12. Every Java Program has a default main thread.
A thread is an independent path of code
execution.
Many threads can run concurrently in a Java
Program.
Threads can be used to perform time-intensive
tasks and run them in the background.
This allows the application to remain responsive
to its users.
Each thread executes runnable object.
Runnables are objects that encapsulate code
sequences.
13. Threads can initiate an asynchronous task.
Asynchronous indicates that it can run
concurrently [at the same time instead of
sequentially]
The JVM gives each thread its own private JVM
stack.
This prevents threads from interfering with each
other.
14. Java supports threads through
Java.lang.Thread Class
java.lang.Runnable interface
Threads are either daemon or non-daemon.
Daemon threads don’t stop the JVM from ending.
Threads by default are non-daemon threads.
Java garbage Collection runs on daemon thread.
The main thread is non-daemon thread.
The program with non-daemon threads have
died.
15.
16. Automatically
The benefit of Java’s multithreading is that the main
loop/polling mechanism is eliminated. One thread can
pause without stopping other parts of your program
As most readers know, over the past few years, multi-core
systems have become commonplace. Of course, single-core
systems are still in widespread use. It is important to
understand that Java’s multithreading features work in
both types of systems.
In a single core system, concurrently executing threads
share the CPU, with each thread receiving a slice of CPU
time. Therefore, in a single-core system, two or more
threads do not actually run at the same time, but idle CPU
time is utilized.
However, in multi-core systems, it is possible for two or
more threads to actually execute simultaneously. In many
cases, this can further improve program efficiency and
increase the speed of certain operations.
17. Automatically
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. Several of those
used in this chapter are shown here:
18. Automatically
When a Java program starts up, one thread
begins running immediately. This is usually
called the main thread of your program,
because it is the one that is executed when
your program begins. The main thread is
important for two reasons:
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.
Program Controlling main thread
19. Automatically
The easiest way to create a thread is to
create a class that implements the Runnable
interface.
run( ) can call other methods, use other
classes, and declare variables, just like the
main thread can. The only difference is that
run( ) establishes the entry point for another,
concurrent thread of execution within your
program. This thread will end when run( )
returns.
22. Automatically
Thread class defines several methods that can
be overridden by a derived class. Of these
methods, the only one that must be overridden
is run( ).
Many Java programmers feel that 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 simply to implement Runnable.
By implementing Runnable, your thread class
does not need to inherit Thread, making it free
to inherit a different class
23. Automatically
Often you will want the main thread to finish
last, use t1.join() in main method to make
main thread waiting for thread object t1.
isalive() returns true for alive thread, false
otherwise
Program (Refer program 6)
24. Automatically
Thread priorities are used by the thread scheduler to decide
when each thread should be allowed to run. In theory, over a
given period of time, higher-priority threads get more CPU time
than lower-priority threads. In practice, the amount of CPU time
that a thread gets often depends on several factors besides its
priority.
For example, how an OS implements multitasking can affect the
relative availability of CPU time. A higher-priority thread can also
preempt a lower-priority one. For instance, when a lower-priority
thread is running and a higher-priority thread resumes.
Sleeping and waiting for I/O example
Program (Refer program 5)
25. Automatically
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.
A monitor is an object that is used as a mutually
exclusive lock. 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.
26. Automatically
Interference happens when two operations, running in
different threads, but acting on the same data, interleave.
This means that the two operations consist of multiple
steps, and the sequences of steps overlap.
27. Automatically
Single expression deposit can
be decomposed into three
steps:
1. Retrieve the current value
of balance.
2. balance += amount
3. Store the incremented
value back in balance.
Single expression withdraw can
be decomposed into three steps:
1. Retrieve the current value
of balance.
2. balance -= amount
3. Store the decremented
value back in balance.
28. Automatically
Suppose Thread A invokes deposit at about the
same time Thread B invokes withdraw. If the
initial value of balance is 500, their interleaved
actions might follow this sequence:
Thread A: Retrieve balance. [500]
Thread B: Retrieve balance. [500]
Thread A: Deposit 1000rs [1500].
Thread B: Withdraw 500rs [0 since Thread B has read
500].
Thread A: Store balance on server; balance is 1500
Thread B: Store balance on server; balance is
overwritten on server and now it is 0.
29. Automatically
To make a method synchronized, simply add the synchronized keyword to
its declaration [Refer program 6]
30. Automatically
While creating synchronized methods within classes that you create
is an easy and effective means of achieving synchronization, it will
not work in all cases. [Refer program 7]
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? Fortunately, the solution to this problem is quite
easy: You simply put calls to the methods defined by this class inside
a synchronized block.
This is the general form of the synchronized statement:
synchronized(objRef) {
// statements to be synchronized
…….
…….
}
Here, objRef is a reference to the object
being synchronized. A synchronized block
ensures that a call to a synchronized method
that is a member of objRef’s class occurs only
after the current thread has successfully
entered objRef’s monitor
31. Automatically
The Object class in Java has three final methods that
allow threads to communicate about the locked
status of a resource. [program – 8 producer, consumer]
These are :
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( ) or
notifyAll( ).
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
32. Automatically
A special type of error that you need to avoid that relates
specifically to multitasking is deadlock, which occurs when
two threads have a circular dependency on a pair of
synchronized objects. For example, suppose one thread
enters the monitor on object X and another thread enters
the monitor on object Y. If the thread in X tries to call any
synchronized method on Y, it will block as expected.
However, if the thread in Y, in turn, tries to call any
synchronized method on X, the thread waits forever,
because to access X, it would have to release its own lock
on Y so that the first thread could complete. Deadlock is a
difficult error to debug for two reasons:
In general, it occurs only rarely, when the two threads
time-slice in just the right way.
It may involve more than two threads and two
synchronized objects. (That is, deadlock can occur
through a more convoluted sequence of events than
just described.) [Refer Deadlock.java program 9]
33. utomatically
A special type of error that you need to avoid that relates
specifically to multitasking is deadlock, which occurs when
two threads have a circular dependency on a pair of
synchronized objects. For example, suppose one thread
enters the monitor on object X and another thread enters
the monitor on object Y. If the thread in X tries to call any
synchronized method on Y, it will block as expected.
However, if the thread in Y, in turn, tries to call any
synchronized method on X, the thread waits forever,
because to access X, it would have to release its own lock
on Y so that the first thread could complete. Deadlock is a
difficult error to debug for two reasons:
In general, it occurs only rarely, when the two threads
time-slice in just the right way.
It may involve more than two threads and two
synchronized objects. (That is, deadlock can occur
through a more convoluted sequence of events than
just described.) [Refer Deadlock.java]
34. JDK 5 added the concurrency utilities, also
commonly referred to as the concurrent API.
Although the original concurrent API was
impressive in its own right, it was significantly
expanded by JDK 7. The most important addition
was the Fork/Join Framework
You can explore Concurrent API Packages
java.util.concurrent
java.util.concurrent.atomic
java.util.concurrent.locks