Advanced Programming-unit 1
Advanced Programming-unit 1
Advanced Programming
CHAPTER ONE :
THREADS
Contents
• Introductions to threads
• Creating a Thread
• Thread Scheduling
• Synchronization
• The Object Monitor
2
What are Threads?
• Processes – are independently running programs that are isolated
from each other.
• Threading - is a facility to allow multiple activities to coexist within
a single process.
• Java is the first programming language to explicitly include
threading within the language itself.
• Threads are sometimes referred to as lightweight processes.
• Like processes, threads are independent, concurrent paths of
execution through a program, and each thread has its own stack, its
own program counter, and its own local variables.
• However, threads within a process are less insulated from each
other than separate processes are.
• They share memory, file handles, and other per-process state.
3
• Most modern operating systems support threads.
• Java is the first mainstream programming language to
explicitly include threading within the language itself, rather
than treating threading as a facility of the underlying operating
system.
4
What are Threads? (contd)
– A process can support multiple threads, which appear to execute
simultaneously and asynchronously to each other.
– More than one thread (program) run simultaneously is known as
multithreading (multiprogramming).
– Multiple threads within a process share the same memory address
space, which means they have access to the same variables and
objects, and they allocate objects from the same heap.
– Every Java program has at least one thread -- the main thread.
– The JVM also creates other threads that are mostly invisible to you
– for example: threads associated with garbage collection and other
JVM housekeeping tasks.
– Other facilities create threads too, such as the AWT (Abstract
Windowing Toolkit) or Swing UI toolkits, servlet containers,
application servers, and RMI (Remote Method Invocation). 5
Why Use Threads?
– Some of the reasons for using threads are that
they can help to:
• Make the UI more responsive
• Take advantage of multiprocessor systems
• Simplify modeling
• Perform asynchronous or background processing
• Allow multiple client connections simultaneously
• Maintain responsiveness of an application during a
long running task
• Speed up tasks when multiple processors available6
Thread Risks
– While the Java thread facility is very easy to use, there are
several risks you should try to avoid when you create
multithreaded programs.
• When multiple threads access the same data item, make
sure that they coordinate their access to a shared data so
that both see a consistent.
• The Java language provides two keywords for this
purpose: synchronized and volatile.
• If you are going to use synchronization to protect access
to shared variables, you must make sure to use it
everywhere in your program where the variable is
accessed.
7
Thread Life Cycle
– A thread can be in one of several possible states through out its life.
1. Newborn State
– When we create a thread it will be in Newborn State.
– The thread is just created still its not running.
– We can move it to running mode by invoking the start() method
and it can be killed by using stop() method.
2. Runnable State
– It means that thread is now ready for running and its waiting to
give control.
– We can move control to another thread by yield() method.
8
Thread Life Cycle (contd)
3. Running State
– It means thread is in its execution mode because the control of
CPU is given to that particular thread.
– It can move in three different situation from running mode.
4. Blocked State
– A thread is called in Blocked State when it is not allowed to
entering in Runnable State or Running State.
– It happens when thread is in waiting, suspended or in sleeping
mode.
5. Dead State
– When a thread is completed executing its run() method the life
cycle of that particular thread is end.
– We can kill thread by invoking stop() method for that particular
9
thread and send it to be in Dead State.
Thread Life Cycle(contd)
10
Thread Methods
void start()
– Creates a new thread and makes it runnable
– This method can be called only once
void run()
– The new thread begins its life inside this method
void stop()
– The thread is being terminated
void yield()
– Causes the currently executing thread object to temporarily
pause and allow other threads to execute
– Allow only threads of the same priority to run
void sleep(int m) or sleep(int m, int n)
– The thread sleeps for m milliseconds, plus n nanoseconds
Creating Threads 11
Creating Thread
– We can create thread in java with two different ways.
1. Extending the Thread Class.
2. Implements Runnable interface.
Example 1:
//A program to find out the thread used by JVM to execute the statements.
class FirstDemo {
public static void main(String[] args) {
System.out.println("Let's find current thread.. ");
Thread th=Thread.currentThread();
System.out.println("Current thread is: "+th);
System.out.println("Thread name is: "+th.getName());
Let's
System.out.println("Thread priority is: find current thread..
"+th.getPriority());
Current thread is: Thread[main,5,main]
System.out.println("Thread is alive: "+th.isAlive());
Thread name is: main
} Thread priority is: 5
Thread is alive: true 12
}
Creating Thread(contd)
1. Extending the Thread class:
– In this method one normal class extends the inbuilt class thread
and override its run() method with the code required by that
particular thread.
– Here we are going to extend class java.lang.Thread.
• Create one class which extends the thread class.
• Override the run method and put lines of code inside
thread method that will be perform by thread.
• Create an object of class which we created with extending
the thread class and call the start() method to execute the
thread.
13
Creating Thread(contd)
• Example: MyThread.
Class MyThread extends Thread
{
………………..
………………..
}
• Implementing the run() method
public void run()
{
……… // Thread code here
}
• Starting new Thread
MyThread aTh = new MyThread(); // instantiates a new
aTh.start(); // invokes run() method
14
Creating Thread(contd)
Example One:
public class ThreadDemo extends Thread{
public static void main(String[] a) {
ThreadDemo t = new ThreadDemo ();
t.start();
System.out.println("Hello world! - From the main program.");
}
public void run() {
System.out.println("Hello world! - From a thread.");
try {
sleep(1000*60*60);
} catch (InterruptedException e) {
System.out.println("Interrupted.");
}
}
Output:
} Hello world! - From the main program. 15
Hello world! - From a thread.
Creating Thread(contd)
• A couple of things you should know about this program:
This program will run (actually sleep) for about one hour, after
printing those messages. So you may need to press Ctrl-C to
terminate the program.
There will be actually two threads running in this program. The
first one is the main thread executing all the statement in the
main() method. The second one is a sub-thread launched by the
t.start() statement.
Notice the order of the messages printed out on the console. It
tells us that the sub-thread took a little bit longer to run its first
statement, after it has been launched by the main thread.
A multi-threading program will not terminate until all its threads
has reached the end of their execution.
The run() method in the Thread is empty, so if you want a
thread to do some work, you need to override the run()
16
method.
Creating Thread(contd)
import java.lang.Thread;
class A extends Thread{
public void run(){
System.out.println("Thread A");
for(int i=1;i<=5;i++){
System.out.println("From thread A i = " + i);
}
System.out.println("Exit from A");
}}
class B extends Thread {
public void run(){
System.out.println("Thread B");
for(int i=1;i<=5;i++){
System.out.println("From thread B i = " + i);
}
System.out.println("Exit from B"); 17
}}
Creating Thread(contd)
public class Demo {
public static void main(String[] args) {
new A().start();//creating A class thread object and calling run method
new B().start();//creating B class thread object and calling run method
System.out.println("End of main thread");
}
} Thread A
From thread A i = 1
From thread A i = 2
From thread A i = 3
From thread A i = 4
• Running the same program will yield different From thread A i = 5
output though our program code is same. Exit from A
End of main thread
• It happens in thread program because they are Thread B
running concurrently on their own. From thread B i = 1
From thread B i = 2
• Threads are running independently of one From thread B i = 3
From thread B i = 4
another and each executes whenever it has a From thread B i = 5
chance. Exit from B 18
Creating Thread(contd)
2) Implementing the Runnable interface:
– In this method we have one interface named runnable and we
implements this interface for implementing a thread.
• Create one class which implements runnable interface.
• Override the run() method and put some line of code for that
particular thread.
• Now create an object of inbuilt thread class and create an object
of class that implements runnable interface.
• Give the reference of object to thread object by passing an
argument (argument must be the object of class which
implements the runnable interface) while creating a thread
object.
• Call the start() method to run the thread.
19
Creating Thread(contd)
Example One:
class ThreadRun implements Runnable {
public static void main(String[] a) {
ThreadRun r = new ThreadRun();
Thread t = new Thread(r);
t.start();
System.out.println("Hello world! - From the main program.");
}
public void run() {
System.out.println("Hello world! - From a thread.");
try {
Thread.sleep(1000*60*60);
} catch (InterruptedException e) {
System.out.println("Interrupted.");
} Output:
Hello world! - From the main program.
}} Hello world! - From a thread. 20
Creating Thread(contd)
• Note that:
The program behaves the same way as the previous program
ThreadDemo which is created using thread objects with thread sub
classes
The Thread object t is created with the special Thread constructor,
which takes a Runnable object as input..
Since our class is not extending the Thread class any more, we need to
call the sleep() explicitly by prefixing the class name: Thread.
• May be you are wondering why we need the second way of creating a
new thread, which seems to be less straight forward than the first way?
The answer is that Java classes can not be extended from two different
base classes. So if you are in a situation where you want to create a new
class by extending an existing class to inherit some nice features of that
class, and you also want to make the new class executable as a thread,
you have to use the second way to implement the "Runnable" interface in
your new class. 21
Creating Thread(contd)
Example Two: Output
End of main Thread
class X implements Runnable {
Inside X thread
public void run() { From xthread i = 1
System.out.println("Inside X thread"); From xthread i = 2
for(int i=1;i<=10;i++) { From xthread i = 3
From xthread i = 4
System.out.println("From xthread i = " +i); From xthread i = 5
} From xthread i = 6
System.out.println("Exit from X"); From xthread i = 7
}} From xthread i = 8
From xthread i = 9
public class Demo{ From xthread i = 10
public static void main(String[] args) { Exit from X
X x1 = new X(); //class object
//creating thread object and giving reference of class object to thread
object
Thread xthread = new Thread(x1);
xthread.start();
System.out.println("End of main Thread");
}}
22
Extending Thread vs. Implementing Runnable Interface
– Choosing between these two is a matter of taste
– Implementing the Runnable interface
• May take more work since we still
– Declare a Thread object
– Call the Thread methods on this object
• Your class can still extend other class
– Extending the Thread class
• Easier to implement
• Your class can no longer extend any other class
23
The Thread Class: Constructor
24
The Thread Class: Constants
• Contains fields for priority values
25
What You Should Know
– A thread doesn't actually begin to execute until another thread
calls the start() method on the Thread object for the new
thread.
– A thread will end in one of three ways:
• The thread comes to the end of its run() method.
• The thread throws an Exception or Error that is not
caught.
• Another thread calls one of the deprecated stop() methods.
– When all the threads within a Java program complete, the
program exits.
– The Thread API contains a method for waiting for another
thread to complete: the join() method.
26
Thread Priority
– Each java thread has its own priority which decides the order of
thread to be schedule.
– The threads of equal priority will be given same treatment by java
scheduler. And they will follow the FCFS (First Come First Serve)
algorithm.
– User can also set the priority of thread by using the setPriority()
method as follow:
ThreadName.setPriority(int Number);
– Here the number is integer value between 1 to 10, Here 1 is
minimum priority 10 is maximum priority.
– The Thread class defines few priority constants:
– MIN_PRIORITY = 1
– NORM_PRIORITY = 5
– MAX_PRIORITY = 10
– In any Thread the default priority is NORM_PRIORITY
27
Thread Scheduling
Scheduling
– Except when using Thread.join() and Object.wait(), the
timing of thread scheduling and execution is
nondeterministic.
– If two threads are running at the same time and neither is
waiting, you must assume that between any two
instructions, other threads may be running and modifying
program variables.
– If your thread will be accessing data that may be visible to
other threads, such as data referenced directly or indirectly
from static fields (global variables), you must use
synchronization to ensure data consistency.
28
Sleeping
– The Thread API includes a sleep() method, which will cause the
current thread to go into a wait state until the specified amount of
time has elapsed or until the thread is interrupted by another
thread calling Thread.interrupt() on the current thread's Thread
object.
• When the specified time elapses, the thread again becomes runnable
and goes back onto the scheduler's queue of runnable threads.
• If a thread is interrupted by a call to Thread.interrupt(), the sleeping
thread will throw an InterruptedException so that the thread will
know that it was awakened by an interrupt and won't have to check to
see if the timer expired.
– The Thread.yield() method is like Thread.sleep(), but instead of
sleeping, it simply pauses the current thread momentarily so that
other threads can run.
– In most implementations, threads with lower priority will not run
29
Daemon Threads
– It’s mentioned that a Java program exits when all of its threads have
completed, but this is not exactly correct.
• What about the hidden system threads, such as the garbage collection
thread and others created by the JVM? We have no way of stopping
these. If those threads are running, how does any Java program ever
exit?
– These system threads are called daemon threads. A Java program
actually exits when all its non-daemon threads have completed.
– Any thread can become a daemon thread.
• You can indicate a thread is a daemon thread by calling the
Thread.setDaemon() method.
• You might want to use daemon threads for background threads that
you create in your programs, such as timer threads or other deferred
event threads, which are only useful while there are other non-
30
daemon threads running.
Sharing variables
– For multiple threads to be useful in a program, they have to
have some way to communicate or share their results with
each other.
– The simplest way for threads to share their results is to use
shared variables.
– They should also use synchronization to ensure that values are
propagated correctly from one thread to another and to prevent
threads from seeing inconsistent intermediate results while
another thread is updating several related data items.
31
Thread Synchronization
Race condition & How to Solve it
– Race conditions occur when multiple, asynchronously
executing threads access the same object (called a shared
resource) returning unexpected (wrong) results
– Example: Threads often need to share a common
resource i.e. a file, with one thread reading from the file
while another thread writes to the file. They can be avoided
by synchronizing the threads which access the shared
resource
Method one An Unsynchronized Example
class PrintStringsThread implements public void run() {
Runnable { System.out.print(this.str1);
Thread thread; try {
String str1, str2; java.lang.Thread.sleep(2000);
PrintStringsThread(String str1, String }catch (InterruptedException ie) { }
str2) { System.out.println(this.str2);
this.str1 = str1; }
this.str2 = str2; }
thread = new java.lang.Thread(this); public class RaceConditionDemo{
thread.start(); public static void main(String[] args) {
} new PrintStringsThread("Hello ",
“comps.");
new PrintStringsThread("How are ",
"you?");
new PrintStringsThread("Thank you ",
"very much!");
}}
An Unsynchronized Example
Sample outputs:
Hello How are Thank you comps. Hello How are Thank you you?
you? very much!
very much! comps.
Hello How are Thank you comps. Hello Thank you How are comps.
very much! very much!
you? you?
Unsynchronized Example
– The biggest problem of allowing multiple threads sharing the same
data set is that one operation in one thread could collide with
another operation in another threads on the same data. When this
happens, the result is un-desirable.
– Let's use a bank application program as an example. Assuming that
the program has multiple threads running, with each thread
connecting one ATM system, and you have a saving account in the
bank with $100.00, now you and your friend are going to two
different ATMs at about the same time, and trying to withdraw
$50.00 from your account, what do you think it will happen?
– If the threads are running independently, the following could
happen:
– Both you and your friend will receive $50.00 each, and your account will still have
$50.00. The bank could lose $50.00.
– The solution to this problem is synchronization.
Synchronization: Locking an Object
– Synchronization is needed in a multi-threading
application to ensure that one thread is updating a shared
data other threads wait and get the updated value.
– Synchronization uses a lock to represent the shared data
to allow each thread to use the lock status to
Synchronize with each other.
– Synchronization code block is a unit of code in a thread
that requires synchronization on a particular lock.
– More synchronization locks or longer synchronization
code blocks slow down application performance.
Synchronization: Locking an Object
• Synchronization is a programming technique that involves 3
elements:
Lock: An object with two states: locked and unlocked.
Synchronized Block: A block of statements that is associated
with a lock.
Synchronization Rule: When a synchronized block is
encountered in a thread of execution, the associated lock will be
checked.
If the lock is locked, the execution will be stopped until the
lock is unlocked. If the lock is unlocked, the lock will be
locked, and the synchronized block of statements will be
executed. When the execution reaches the end of the
synchronized block, the lock will be unlocked. With this rule,
two synchronized blocks associated with same lock will never
be executed at the same time.
How Java Supports Synchronization?
– Instead of let the programmers to design their own locks,
manage the synchronization blocks, and apply the
synchronization rules, Java offers a synchronization
monitor on each instance of the Object class, so it can be
used as a synchronization lock. Since all classes are sub
classes of Object, all objects in Java can be used as
synchronization locks.
– Java also offers three ways to define synchronized
blocks.
How Java Supports Synchronization?
Way 1) Synchronized Class Method:
class class_name {
static synchronized return_type method_name() {
//statement block
}
}
• All the statements in the method become the
synchronized block, and the class object is the lock.
How Java Supports Synchronization?
Way 2) Synchronized Instance Method:
class class_name {
synchronized return_type method_name() {
//statement block
}
}
• All the statements in the method become the
synchronized block, and the instance object is the lock.
How Java Supports Synchronization?
Way 3) Synchronized Statement:
class class_name {
return_type method_name() {
synchronized (object) {
statement block
}
}
}
• All the statements specified in the parentheses of the synchronized
statement become the synchronized block, and the object
specified in the statement is the lock.
How Java Supports Synchronization?
• For example, the following code defines two synchronized blocks.
Both are associated with the same lock, the instance object.
class class_name {
type method_name() {
synchronized (this) {
statement block 1
}
}
synchronized type method_name() {
statement block 2
}
}
• Block 1 will never be executed at the same time as block 2.
Deposit as a Synchronized method
• Assume we have a method called deposit in Account class. So here is
how to make it synchronized.
class Account {
int balance=0;
48