7/31/2019 PROGRAMMING PARADIGMS - Unit V
1/33
UNIT V
Multi Threading:
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 iscalled a thread, and each thread defines a separate path of execution.
A multithreading is a specialized form of multitasking. Multitasking threads require
less overhead than multitasking processes.
A process consists of the memory space allocated by the operating system that can
contain one or more threads. A thread cannot exist on its own; it must be a part of a process.
A process remains running until all of the non-daemon threads are done executing.
Multithreading enables you to write very efficient programs that make maximum use
of the CPU, because idle time can be kept to a minimum.
Life Cycle of a Thread:
A thread goes through various stages in its life cycle. For example, a thread is born,
started, runs, and then dies. Following diagram shows complete life cycle of a thread.
Above mentioned stages are explained here:
New: A new thread begins its life cycle in the new state. It remains in this state untilthe program starts the thread. It is also referred to as a born thread.
Runnable: After a newly born thread is started, the thread becomes runnable. A threadin this state is considered to be executing its task.
7/31/2019 PROGRAMMING PARADIGMS - Unit V
2/33
Waiting: Sometimes a thread transitions to the waiting state while the thread waits foranother thread to perform a task.A thread transitions back to the runnable state only
when another thread signals the waiting thread to continue executing.
Timed waiting: A runnable thread can enter the timed waiting state for a specifiedinterval of time. A thread in this state transitions back to the runnable state when that
time interval expires or when the event it is waiting for occurs. Terminated: A runnable thread enters the terminated state when it completes its task
or otherwise terminates.
Thread Properties:
Thread Priorities:
Every Java thread has a priority that helps the operating system determine the order in which
threads are scheduled.
Java priorities are in the range between MIN_PRIORITY (a constant of 1) and
MAX_PRIORITY (a constant of 10). By default, every thread is given priority
NORM_PRIORITY (a constant of 5).
Threads with higher priority are more important to a program and should be allocated
processor time before lower-priority threads. However, thread priorities cannot guarantee the
order in which threads execute and very much platform dependentant.
Creating a Thread:
Java defines two ways in which this can be accomplished:
You can implement the Runnable interface. You can extend the Thread class, itself.
Create Thread by Implementing Runnable:
The easiest way to create a thread is to create a class that implements the Runnable interface.
To implement Runnable, a class need only implement a single method called run( ), which isdeclared like this:
public void run( )
You will define the code that constitutes the new thread inside run() method. It is important
to understand that run() can call other methods, use other classes, and declare variables, just
like the main thread can.
After you create a class that implements Runnable, you will instantiate an object of type
Thread from within that class. Thread defines several constructors. The one that we will useis shown here:
7/31/2019 PROGRAMMING PARADIGMS - Unit V
3/33
Thread(Runnable threadOb, String threadName);
Here threadOb is an instance of a class that implements the Runnable interface and the name
of the new thread is specified by threadName.
After the new thread is created, it will not start running until you call its start( ) method,
which is declared within Thread. The start( ) method is shown here:
void start( );
Example:
Here is an example that creates a new thread and starts it running:
// Create a new thread.
class NewThread implements Runnable {
Thread t;
NewThread() {
// Create a new, second thread
t = new Thread(this, "Demo Thread");
System.out.println("Child thread: " + t);
t.start(); // Start the thread
}
// This is the entry point for the second thread.public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
// Let the thread sleep for a while.
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
class ThreadDemo {
public static void main(String args[]) {
new NewThread(); // create a new thread
try {
for(int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(1000);}
7/31/2019 PROGRAMMING PARADIGMS - Unit V
4/33
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
This would produce following result:
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3Child Thread: 2
Main Thread: 3
Child Thread: 1
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.
Create Thread by 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.
The extending class must override the run( ) method, which is the entry point for the new
thread. It must also call start( ) to begin execution of the new thread.
Example:
Here is the preceding program rewritten to extend Thread:
// Create a second thread by extending Thread
class NewThread extends Thread {
NewThread() {
// Create a new, second thread
super("Demo Thread");
System.out.println("Child thread: " + this);
start(); // Start the thread
}
// This is the entry point for the second thread.
public void run() {try {
7/31/2019 PROGRAMMING PARADIGMS - Unit V
5/33
for(int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
// Let the thread sleep for a while.
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
class ExtendThread {
public static void main(String args[]) {
new NewThread(); // create a new thread
try {for(int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
This would produce following result:
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3
Child Thread: 2
Main Thread: 3Child Thread: 1
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.
Thread Methods:
Following is the list of important medthods available in the Thread class.
7/31/2019 PROGRAMMING PARADIGMS - Unit V
6/33
SN Methods with Description
1
public void start()
Starts the thread in a separate path of execution, then invokes the run() method on this
Thread object.
2
public void run()
If this Thread object was instantiated using a separate Runnable target, the run() method
is invoked on that Runnable object.
3
public final void setName(String name)
Changes the name of the Thread object. There is also a getName() method for retrieving
the name.
4public final void setPriority(int priority)
Sets the priority of this Thread object. The possible values are between 1 and 10.
5 public final void setDaemon(boolean on)A parameter of true denotes this Thread as a daemon thread.
6
public final void join(long millisec)
The current thread invokes this method on a second thread, causing the current thread to
block until the second thread terminates or the specified number of milliseconds passes.
7public void interrupt()
Interrupts this thread, causing it to continue execution if it was blocked for any reason.
8
public final boolean isAlive()
Returns true if the thread is alive, which is any time after the thread has been started but
before it runs to completion.
The previous methods are invoked on a particular Thread object. The following methods in
the Thread class are static. Invoking one of the static methods performs the operation on the
currently running thread
SN Methods with Description
1
public static void yield()
Causes the currently running thread to yield to any other threads of the same priority that
are waiting to be scheduled
2
public static void sleep(long millisec)
Causes the currently running thread to block for at least the specified number of
milliseconds
3public static boolean holdsLock(Object x)
Returns true if the current thread holds the lock on the given Object.
4
public static Thread currentThread()
Returns a reference to the currently running thread, which is the thread that invokes this
method.
5 public static void dumpStack()
7/31/2019 PROGRAMMING PARADIGMS - Unit V
7/33
Prints the stack trace for the currently running thread, which is useful when debugging a
multithreaded application.
Example:
The following ThreadClassDemo program demonstrates some of these methods of the Thread
class:
// File Name : DisplayMessage.java
// Create a thread to implement Runnable
public class DisplayMessage implements Runnable
{
private String message;
public DisplayMessage(String message)
{
this.message = message;
}
public void run()
{
while(true)
{
System.out.println(message);
}
}
}
// File Name : GuessANumber.java
// Create a thread to extentd Thread
public class GuessANumber extends Thread
{
private int number;
public GuessANumber(int number)
{
this.number = number;
}
public void run()
{int counter = 0;
int guess = 0;
do
{
guess = (int) (Math.random() * 100 + 1);
System.out.println(this.getName()
+ " guesses " + guess);
counter++;
}while(guess != number);
System.out.println("** Correct! " + this.getName()
+ " in " + counter + " guesses.**");
7/31/2019 PROGRAMMING PARADIGMS - Unit V
8/33
}
}
// File Name : ThreadClassDemo.java
public class ThreadClassDemo
{
public static void main(String [] args)
{
Runnable hello = new DisplayMessage("Hello");
Thread thread1 = new Thread(hello);
thread1.setDaemon(true);
thread1.setName("hello");
System.out.println("Starting hello thread...");
thread1.start();
Runnable bye = new DisplayMessage("Goodbye");Thread thread2 = new Thread(hello);
thread2.setPriority(Thread.MIN_PRIORITY);
thread2.setDaemon(true);
System.out.println("Starting goodbye thread...");
thread2.start();
System.out.println("Starting thread3...");
Thread thread3 = new GuessANumber(27);
thread3.start();
try
{thread3.join();
}catch(InterruptedException e)
{
System.out.println("Thread interrupted.");
}
System.out.println("Starting thread4...");
Thread thread4 = new GuessANumber(75);
thread4.start();
System.out.println("main() is ending...");
}}
This would produce following result. You can try this example again and again and you
would get different result every time.
Starting hello thread...
Starting goodbye thread...
Hello
Hello
Hello
7/31/2019 PROGRAMMING PARADIGMS - Unit V
9/33
Hello
Hello
Hello
Hello
Hello
Hello
Thread-2 guesses 27
Hello
** Correct! Thread-2 in 102 guesses.**
Hello
Starting thread4...
Hello
Hello
..........remaining result produced.
Thread 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 synchronization is achieved is called thread synchronization.
The synchronized keyword in Java creates a block of code referred to as a critical section.
Every Java object with a critical section of code gets a lock associated with the object. To
enter a critical section, a thread needs to obtain the corresponding object's lock.
This is the general form of the synchronized statement:
synchronized(object) {
// statements to be synchronized
}
Here, object is a reference to the object being synchronized. A synchronized block ensuresthat a call to a method that is a member of object occurs only after the current thread has
successfully entered object's monitor.
Here is an example, using a synchronized block within the run( ) method:
// File Name : Callme.java
// This program uses a synchronized block.
class Callme {
void call(String msg) {
System.out.print("[" + msg);try {
7/31/2019 PROGRAMMING PARADIGMS - Unit V
10/33
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println("]");
}
}
// File Name : Caller.java
class Caller implements Runnable {
String msg;
Callme target;
Thread t;
public Caller(Callme targ, String s) {
target = targ;
msg = s;t = new Thread(this);
t.start();
}
// synchronize calls to call()
public void run() {
synchronized(target) { // synchronized block
target.call(msg);
}
}
}// File Name : Synch.java
class Synch {
public static void main(String args[]) {
Callme target = new Callme();
Caller ob1 = new Caller(target, "Hello");
Caller ob2 = new Caller(target, "Synchronized");
Caller ob3 = new Caller(target, "World");
// wait for threads to end
try {
ob1.t.join();ob2.t.join();
ob3.t.join();
} catch(InterruptedException e) {
System.out.println("Interrupted");
}
}
}
This would produce following result:
7/31/2019 PROGRAMMING PARADIGMS - Unit V
11/33
[Hello]
[World]
[Synchronized]
Interthread Communication:
Consider the classic queuing problem, where one thread is producing some data and another
is consuming it. To make the problem more interesting, suppose that the producer has to wait
until the consumer is finished before it generates more data.
In a polling system, the consumer would waste many CPU cycles while it waited for the
producer to produce. Once the producer was finished, it would start polling, wasting more
CPU cycles waiting for the consumer to finish, and so on. Clearly, this situation is
undesirable.
To avoid polling, Java includes an elegant interprocess communication mechanism via the
following methods:
wait( ): This method tells the calling thread to give up the monitor and go to sleepuntil some other thread enters the same monitor and calls notify( ).
notify( ): This method wakes up the first thread that called wait( ) on the same object. notifyAll( ): This method wakes up all the threads that called wait( ) on the same
object.c The highest priority thread will run first.
These methods are implemented as final methods in Object, so all classes have them. All
three methods can be called only from within a synchronized context.
These methods are declared within Object. Various forms of wait( ) exist that allow you to
specify a period of time to wait.
Example:
The following sample program consists of four classes: Q, the queue that you're trying to
synchronize; Producer, the threaded object that is producing queue entries; Consumer, the
threaded object that is consuming queue entries; and PC, the tiny class that creates the singleQ, Producer, and Consumer.
The proper way to write this program in Java is to use wait( ) and notify( ) to signal in bothdirections, as shown here:
class Q {
int n;
boolean valueSet = false;
synchronized int get() {
if(!valueSet)
try {
wait();
} catch(InterruptedException e) {System.out.println("InterruptedException caught");
7/31/2019 PROGRAMMING PARADIGMS - Unit V
12/33
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
if(valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
valueSet = true;System.out.println("Put: " + n);
notify();
}
}
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}
}
class Consumer implements Runnable {
Q q;Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}
}
class PCFixed {
7/31/2019 PROGRAMMING PARADIGMS - Unit V
13/33
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}
Inside get( ), wait( ) is called. This causes its execution to suspend until the Producer notifies
you that some data is ready.
When this happens, execution inside get( ) resumes. After the data has been obtained, get( )
calls notify( ). This tells Producer that it is okay to put more data in the queue.
Inside put( ), wait( ) suspends execution until the Consumer has removed the item from thequeue. When execution resumes, the next item of data is put in the queue, and notify( ) is
called. This tells the Consumer that it should now remove it.
Here is some output from this program, which shows the clean synchronous behavior:
Put: 1
Got: 1
Put: 2
Got: 2
Put: 3Got: 3
Put: 4
Got: 4
Put: 5
Got: 5
Thread Deadlock:
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 ofsynchronized 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.
Example:
7/31/2019 PROGRAMMING PARADIGMS - Unit V
14/33
To understand deadlock fully, it is useful to see it in action. The next example creates two
classes, A and B, with methods foo( ) and bar( ), respectively, which pause briefly before
trying to call a method in the other class.
The main class, named Deadlock, creates an A and a B instance, and then starts a second
thread to set up the deadlock condition. The foo( ) and bar( ) methods use sleep( ) as a way toforce the deadlock condition to occur.
class A {
synchronized void foo(B b) {
String name = Thread.currentThread().getName();
System.out.println(name + " entered A.foo");
try {
Thread.sleep(1000);
} catch(Exception e) {
System.out.println("A Interrupted");}
System.out.println(name + " trying to call B.last()");
b.last();
}
synchronized void last() {
System.out.println("Inside A.last");
}
}
class B {
synchronized void bar(A a) {
String name = Thread.currentThread().getName();System.out.println(name + " entered B.bar");
try {
Thread.sleep(1000);
} catch(Exception e) {
System.out.println("B Interrupted");
}
System.out.println(name + " trying to call A.last()");
a.last();
}
synchronized void last() {
System.out.println("Inside A.last");}
}
class Deadlock implements Runnable {
A a = new A();
B b = new B();
Deadlock() {
Thread.currentThread().setName("MainThread");
Thread t = new Thread(this, "RacingThread");
t.start();
a.foo(b); // get lock on a in this thread.
System.out.println("Back in main thread");
7/31/2019 PROGRAMMING PARADIGMS - Unit V
15/33
}
public void run() {
b.bar(a); // get lock on b in other thread.
System.out.println("Back in other thread");
}
public static void main(String args[]) {
new Deadlock();
}
}
Here is some output from this program:
MainThread entered A.foo
RacingThread entered B.bar
MainThread trying to call B.last()RacingThread trying to call A.last()
Because the program has deadlocked, you need to press CTRL-C to end the program. Youcan see a full thread and monitor cache dump by pressing CTRL-BREAK on a PC .
You will see that RacingThread owns the monitor on b, while it is waiting for the monitor on
a. At the same time, MainThread owns a and is waiting to get b. This program will never
complete.
As this example illustrates, if your multithreaded program locks up occasionally, deadlock isone of the first conditions that you should check for.
Thread Control:
While the suspend( ), resume( ), and stop( ) methods defined by Thread class seem to be a
perfectly reasonable and convenient approach to managing the execution of threads, they
must not be used for new Java programs and obsolete in newer versions of Java.
The following example illustrates how the wait( ) and notify( ) methods that are inherited
from Object can be used to control the execution of a thread.
This example is similar to the program in the previous section. However, the deprecated
method calls have been removed. Let us consider the operation of this program.
The NewThread class contains a boolean instance variable named suspendFlag, which is used
to control the execution of the thread. It is initialized to false by the constructor.
The run( ) method contains a synchronized statement block that checks suspendFlag. If that
variable is true, the wait( ) method is invoked to suspend the execution of the thread. The
mysuspend( ) method sets suspendFlag to true. The myresume( ) method sets suspendFlag to
false and invokes notify( ) to wake up the thread. Finally, the main( ) method has been
modified to invoke the mysuspend( ) and myresume( ) methods.
7/31/2019 PROGRAMMING PARADIGMS - Unit V
16/33
Example:
// Suspending and resuming a thread for Java 2
class NewThread implements Runnable {
String name; // name of thread
Thread t;
boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
suspendFlag = false;
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {try {
for(int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
while(suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
suspendFlag = true;
}
synchronized void myresume() {
suspendFlag = false;
notify();
}}
class SuspendResume {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending thread One");
Thread.sleep(1000);
7/31/2019 PROGRAMMING PARADIGMS - Unit V
17/33
ob1.myresume();
System.out.println("Resuming thread One");
ob2.mysuspend();
System.out.println("Suspending thread Two");
Thread.sleep(1000);
ob2.myresume();
System.out.println("Resuming thread Two");
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
// wait for threads to finish
try {
System.out.println("Waiting for threads to finish.");
ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
Here is the output produced by the above program:
New thread: Thread[One,5,main]
One: 15New thread: Thread[Two,5,main]
Two: 15
One: 14
Two: 14
One: 13
Two: 13
One: 12
Two: 12
One: 11
Two: 11
Suspending thread OneTwo: 10
Two: 9
Two: 8
Two: 7
Two: 6
Resuming thread One
Suspending thread Two
One: 10
One: 9
One: 8
One: 7
7/31/2019 PROGRAMMING PARADIGMS - Unit V
18/33
One: 6
Resuming thread Two
Waiting for threads to finish.
Two: 5
One: 5
Two: 4
One: 4
Two: 3
One: 3
Two: 2
One: 2
Two: 1
One: 1
Two exiting.
One exiting.
Main thread exiting.
Using isAlive() and join():
Typically, the main thread is the last thread to finish in a program. However, there isnt any
guarantee that the main thread wont finish before a child thread finishes. In the previous
example, we told the main method to sleep until the child threads terminate. However, we
estimated the time it takes for the child threads to complete processing. If our estimate was
too short, a child thread could terminate after the main thread terminates. Therefore, the sleep
technique isnt the best one to use to guarantee that the main thread terminates last.
Programmers use two other techniques to ensure that the main thread is the last thread to
terminate. These techniques involve calling the isAlive() method and the join() method. Both
of these methods are defined in the Thread class.
The isAlive() method determines whether a thread is still running. If it is, the isAlive()
method returns a Boolean true value; otherwise, a Boolean false is returned. You can use the
isAlive() method to examine whether a child thread continues to run. The join() method
works differently than the isAlive() method. The join() method waits until the child thread
terminates and joins the main thread. In addition, you can use the join() method to specify
the amount of time you want to wait for a child thread to terminate.
The following example illustrates how to use the isAlive() method and the join() method in
your program. This example is nearly the same as the previous example. The difference lies
in the main() method of the Demo class definition.
After the threads are declared using the constructor of the MyThread class, the isAlive()
method is called for each thread. The value returned by the isAlive() method is then displayed
on the screen. Next, the join() method is called for each thread. The join() method causes the
main thread to wait for all child threads to complete processing before the main thread
terminates.
class MyThread implements Runnable {
7/31/2019 PROGRAMMING PARADIGMS - Unit V
19/33
String tName;
Thread t;
MyThread (String threadName) {
tName = threadName;
t = new Thread (this, tName);
t.start();
}
public void run() {
try {
System.out.println("Thread: " + tName );
Thread.sleep(2000);
} catch (InterruptedException e ) {
System.out.println("Exception: Thread "
+ tName + " interrupted");
}
System.out.println("Terminating thread: " + tName );}
}
class Demo {
public static void main (String args []) {
MyThread thread1 = new MyThread ("1");
MyThread thread2 = new MyThread ("2");
MyThread thread3 = new MyThread ("3");
MyThread thread4 = new MyThread ("4");
System.out.println("Thread Status: Alive");
System.out.println("Thread 1: "
+ thread1.t.isAlive());System.out.println("Thread 2: "
+ thread2.t.isAlive());
System.out.println("Thread 3: "
+ thread3.t.isAlive());
System.out.println("Thread 4: "
+ thread4.t.isAlive());
try {
System.out.println("Threads Joining.");
thread1.t.join();
thread2.t.join();
thread3.t.join();thread4.t.join();
} catch (InterruptedException e) {
System.out.println(
"Exception: Thread main interrupted.");
}
System.out.println("Thread Status: Alive");
System.out.println("Thread 1: "
+ thread1.t.isAlive());
System.out.println("Thread 2: "
+ thread2.t.isAlive());
System.out.println("Thread 3: "
7/31/2019 PROGRAMMING PARADIGMS - Unit V
20/33
+ thread3.t.isAlive());
System.out.println("Thread 4: "
+ thread4.t.isAlive());
System.out.println(
"Terminating thread: main thread.");
}
}
Here is what is displayed on the screen when this program runs:
Thread Status: Alive
Thread 1: trueThread 2: true
Thread 3: true
Thread 4: true
Threads Joining.
Thread: 1
Thread: 2
Thread: 3
Thread: 4
Terminating thread: 1
Terminating thread: 2
Terminating thread: 3Terminating thread: 4
Thread Status: Alive
Thread 1: false
Thread 2: false
Thread 3: false
Thread 4: false
Terminating thread: main thread.
Interrupting Thread:
The method is public void interrupt()
Interrupts this thread.
Unless the current thread is interrupting itself, which is always permitted, the
checkAccess method of this thread is invoked, which may cause a SecurityException
to be thrown.
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int)
methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), orsleep(long, int), methods of this class, then its interrupt status will be cleared and it
http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#checkAccess%28%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/SecurityException.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#wait%28%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#wait%28long%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#wait%28long,%20int%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join%28%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join%28long%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join%28long,%20int%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#sleep%28long%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#sleep%28long,%20int%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#sleep%28long,%20int%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#sleep%28long%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join%28long,%20int%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join%28long%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join%28%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#wait%28long,%20int%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#wait%28long%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#wait%28%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/SecurityException.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#checkAccess%28%297/31/2019 PROGRAMMING PARADIGMS - Unit V
21/33
will receive an InterruptedException.
If this thread is blocked in an I/O operation upon an interruptible channel then the
channel will be closed, the thread's interrupt status will be set, and the thread will
receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt status will be set and it
will return immediately from the selection operation, possibly with a non-zero value,
just as if the selector's wakeup method were invoked.
If none of the previous conditions hold then this thread's interrupt status will be set.
Throws:
SecurityException - if the current thread cannot modify this thread
public class SleepInterrupt implements Runnable {public void run() {
try {
System.out.println("in run() - sleep for 20 seconds");
Thread.sleep(20000);
System.out.println("in run() - woke up");
} catch (InterruptedException x) {
System.out.println("in run() - interrupted while sleeping");
return;
}
System.out.println("in run() - leaving normally");
}
public static void main(String[] args) {
SleepInterrupt si = new SleepInterrupt();
Thread t = new Thread(si);
t.start();
// Be sure that the new thread gets a chance to
// run for a while.
try {
Thread.sleep(2000);
} catch (InterruptedException x) {}
System.out.println("in main() - interrupting other thread");
t.interrupt();
System.out.println("in main() - leaving");
}
}
Executors:
http://download.oracle.com/javase/1.5.0/docs/api/java/lang/InterruptedException.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/nio/channels/InterruptibleChannel.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/nio/channels/ClosedByInterruptException.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/nio/channels/Selector.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/nio/channels/Selector.html#wakeup%28%29http://download.oracle.com/javase/1.5.0/docs/api/java/lang/SecurityException.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/lang/SecurityException.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/nio/channels/Selector.html#wakeup%28%29http://download.oracle.com/javase/1.5.0/docs/api/java/nio/channels/Selector.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/nio/channels/ClosedByInterruptException.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/nio/channels/InterruptibleChannel.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/lang/InterruptedException.html7/31/2019 PROGRAMMING PARADIGMS - Unit V
22/33
There's a close connection between the task being done by a new thread, as defined by its
Runnable object, and the thread itself, as defined by a Thread object. This works well for
small applications, but in large-scale applications, it makes sense to separate thread
management and creation from the rest of the application. Objects that encapsulate these
functions are known as executors. The following subsections describe executors in detail.
Thread Pools
Most of the executor implementations in java.util.concurrent use thread pools, which consist
ofworker threads. This kind of thread exists separately from the Runnable and Callable tasks
it executes and is often used to execute multiple tasks.
Using worker threads minimizes the overhead due to thread creation. Thread objects use asignificant amount of memory, and in a large-scale application, allocating and deallocating
many thread objects creates a significant memory management overhead.
One common type of thread pool is thefixed thread pool. This type of pool always has a
specified number of threads running; if a thread is somehow terminated while it is still in use,
it is automatically replaced with a new thread. Tasks are submitted to the pool via an internal
queue, which holds extra tasks whenever there are more active tasks than threads.
An important advantage of the fixed thread pool is that applications using it degrade
gracefully. To understand this, consider a web server application where each HTTP request is
handled by a separate thread. If the application simply creates a new thread for every newHTTP request, and the system receives more requests than it can handle immediately, the
application will suddenly stop responding to all requests when the overhead of all those
threads exceed the capacity of the system. With a limit on the number of the threads that can
be created, the application will not be servicing HTTP requests as quickly as they come in,
but it will be servicing them as quickly as the system can sustain.
A simple way to create an executor that uses a fixed thread pool is to invoke the
newFixedThreadPool factory method in java.util.concurrent.Executors This class also
provides the following factory methods:
The newCachedThreadPool method creates an executor with an expandablethread pool. This executor is suitable for applications that launch many short-
lived tasks.
The newSingleThreadExecutor method creates an executor that executes asingle task at a time.
Several factory methods are ScheduledExecutorService versions of the aboveexecutors.
If none of the executors provided by the above factory methods meet your needs,
constructing instances ofjava.util.concurrent.ThreadPoolExecutoror
java.util.concurrent.ScheduledThreadPoolExecutor will give you additional options.
http://download.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool%28int%29http://download.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.htmlhttp://download.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool%28int%29http://download.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor%28int%29http://download.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.htmlhttp://download.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.htmlhttp://download.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.htmlhttp://download.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.htmlhttp://download.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor%28int%29http://download.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool%28int%29http://download.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.htmlhttp://download.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool%28int%297/31/2019 PROGRAMMING PARADIGMS - Unit V
23/33
Callables:
Callables are a tweak to the existing runnable construct. Callables differ only by having a
generic return type - most specialized concurrency APIs already available (such as Foxtrot )
already have the concept of a runnable + return type (such as the foxtrot Task and Job
classes). Some of you may already have noticed that the ExecutorService API is biased to
Callable objects - and some may consider that a problem since they have a lot of code that
already works with Runnable .
public class ComplexCalculation implements Callable {
public ComplexCalculation(int value1, int value2, long value3) {
// ...
}
public Long call() {
// perform complex calculation resulting in long
long result = //...return result; // autoboxing!
}
}
java.util.concurrent
Interface Callable
Type Parameters:
V - the result type of method call
public interface Callable
A task that returns a result and may throw an exception. Implementors define a single method
with no arguments called call.
The Callable interface is similar to Runnable, in that both are designed for classes whose
instances are potentially executed by another thread. A Runnable, however, does not return a
result and cannot throw a checked exception.
The Executors class contains utility methods to convert from other common forms to Callable
classes.
V call()
Computes a result, or throws an exception if unable to do so.
Example:
http://foxtrot.sourceforge.net/http://foxtrot.sourceforge.net/docs/api.phphttp://download.oracle.com/javase/1.5.0/docs/api/java/lang/Runnable.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Executors.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html#call%28%29http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html#call%28%29http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Executors.htmlhttp://download.oracle.com/javase/1.5.0/docs/api/java/lang/Runnable.htmlhttp://foxtrot.sourceforge.net/docs/api.phphttp://foxtrot.sourceforge.net/7/31/2019 PROGRAMMING PARADIGMS - Unit V
24/33
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class SimpExec {public static void main(String args[]) {
CountDownLatch cdl = new CountDownLatch(5);
CountDownLatch cdl2 = new CountDownLatch(5);
CountDownLatch cdl3 = new CountDownLatch(5);
CountDownLatch cdl4 = new CountDownLatch(5);
ExecutorService es = Executors.newFixedThreadPool(2);
es.execute(new MyThread(cdl, "A"));
es.execute(new MyThread(cdl2, "B"));
es.execute(new MyThread(cdl3, "C"));
es.execute(new MyThread(cdl4, "D"));
try {
cdl.await();
cdl2.await();
cdl3.await();
cdl4.await();
} catch (InterruptedException exc) {
System.out.println(exc);}
es.shutdown();
}
}
class MyThread implements Runnable {
String name;
CountDownLatch latch;
MyThread(CountDownLatch c, String n) {
latch = c;
name = n;
new Thread(this);
}
public void run() {
for (int i = 0; i < 5; i++) {
latch.countDown();
7/31/2019 PROGRAMMING PARADIGMS - Unit V
25/33
}
}
}
Synchronizers:
Java 5 introduces general purpose synchronizer classes, including semaphores, mutexes,
barriers, latches, and exchangers, which facilitate coordination between threads. These
classes are a apart of the java.util.concurrent package. A brief description of each of these
follows:
Semaphores
A counting semaphore maintains a set of permits. Each acquire() blocks if necessary
until a permit is available, and then takes it. Each release() adds a permit, potentially
releasing a blocking acquirer. However, no actual permit objects are used; the Semaphore just
keeps a count of the number available and acts accordingly.
Semaphores are often used to restrict the number of threads than can access some (physical or
logical) resource.
Example:
import java.util.concurrent.Semaphore;
import java.util.Random;
//Solving the mutual exclusion problem using Semaphore class
class Process2 extends Thread
{
private static final Random rand = new Random();
private int id;
private Semaphore sem;
public Process2(int i, Semaphore s)
{
id = i;sem = s;
}
private void busy()
{
try
{
sleep(rand.nextInt(500));
} catch (InterruptedException e)
{
}
}
7/31/2019 PROGRAMMING PARADIGMS - Unit V
26/33
private void noncritical()
{
System.out.println("Thread " + id + " is NON critical");
busy();
}
private void critical()
{
System.out.println("Thread " + id + " entering critical section");
busy();
System.out.println("Thread " + id + " leaving critical section");
}
public void run()
{
for (int i = 0; i < 2; ++i){
noncritical();
try
{
sem.acquire();
} catch (InterruptedException e)
{
// ...
}
critical();
sem.release();
}
}
public static void main(String[] args)
{
final int N = 4;
System.out.println("Busy waiting...");
//Semaphore(int permits, boolean fair)Semaphore sem = new Semaphore(N, true);
Process2[] p = new Process2[N];
for (int i = 0; i < N; i++)
{
p[i] = new Process2(i, sem);
p[i].start();
}
}
}
7/31/2019 PROGRAMMING PARADIGMS - Unit V
27/33
Barrier
A synchronization aid that allows a set of threads to all wait for each other to reach a
common barrier point. CyclicBarriers are useful in programs involving a fixed sized group of
threads that must occasionally wait for each other. The barrier is called cyclic because it can
be re-used after the waiting threads are released.
For the java.util.concurrent class see CyclicBarrier
A barrier is a type of synchronization method. A barrier for a group of threads or processes in
the source code means any thread/process must stop at this point and cannot proceed until all
other threads/processes reach this barrier.[1]
The basic Java synchronization mechanism centers on the keyword synchronized, which
predicates methods. In java, all objects can be used like monitors (protected types).
That means that given an object A, no more than one thread can execute a synchronized
method of A at any time.
Barrier implementation/*
* Given object A, no more than one thread can execute a synchronized
method of A at any time.
*/
public class Barrier{
public synchronized void block() throws InterruptedException
{
wait();
}
public synchronized void release() throws InterruptedException
{
notify();
}
public synchronized void releaseAll() throws InterruptedException
{
notifyAll();
}
}
And an example with two threads.
class BarrierExample{
http://programmingexamples.wikidot.com/cyclicbarrierhttp://programmingexamples.wikidot.com/synchronizedhttp://programmingexamples.wikidot.com/synchronizedhttp://programmingexamples.wikidot.com/cyclicbarrier7/31/2019 PROGRAMMING PARADIGMS - Unit V
28/33
static class MyThread1 implements Runnable
{
public MyThread1(Barrier barrier)
{
this.barrier = barrier;}
public void run()
{
try
{
Thread.sleep(1000);
System.out.println("MyThread1 waiting on barrier");
barrier.block();
System.out.println("MyThread1 has been released");
} catch (InterruptedException ie){
System.out.println(ie);
}
}
private Barrier barrier;
}
static class MyThread2 implements Runnable
{
Barrier barrier;
public MyThread2(Barrier barrier)
{
this.barrier = barrier;
}
public void run()
{
try{
Thread.sleep(3000);
System.out.println("MyThread2 releasing blocked threads\n");
barrier.release();
System.out.println("MyThread1 releasing blocked threads\n");
} catch (InterruptedException ie)
{
System.out.println(ie);
}
}
}
7/31/2019 PROGRAMMING PARADIGMS - Unit V
29/33
public static void main(String[] args) throws InterruptedException
{
/*
* MyThread1 MyThread2
* ... ...
* BR.block(); ...* ... BR.release();
*/
Barrier BR = new Barrier();
Thread t1 = new Thread(new BarrierExample.MyThread1(BR));
Thread t2 = new Thread(new BarrierExample.MyThread2(BR));
t1.start();
t2.start();
t1.join();
t2.join();
}
}
Exchangers
A synchronization point at which two threads can exchange objects. Each thread
presents some object on entry to the exchange method, and receives the object presented by
the other thread on return.
Example:
import java.util.concurrent.Exchanger;
class ExgrDemo {
public static void main(String args[]) {
Exchanger exgr = new Exchanger();
new UseString(exgr);
new MakeString(exgr);
}
}
class MakeString implements Runnable {
Exchanger ex;
String str;
MakeString(Exchanger c) {
ex = c;
str = new String();
new Thread(this).start();
}
7/31/2019 PROGRAMMING PARADIGMS - Unit V
30/33
public void run() {
char ch = 'A';
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++)str += (char) ch++;
try {
str = ex.exchange(str);
} catch (InterruptedException exc) {
System.out.println(exc);
}
}
}
}
class UseString implements Runnable {
Exchanger ex;
String str;
UseString(Exchanger c) {
ex = c;
new Thread(this).start();}
public void run() {
for (int i = 0; i < 3; i++) {
try {
str = ex.exchange(new String());
System.out.println("Got: " + str);
} catch (InterruptedException exc) {
System.out.println(exc);
}
}
}
}
Latches
A synchronization aid that allows one or more threads to wait until a set of operations
being performed in other threads completes. A CountDownLatch is initialized with a given
count. The await methods block until the current count reaches zero due to invocations of the
countDown() method, after which all waiting threads are released and any subsequent
invocations of await return immediately.
7/31/2019 PROGRAMMING PARADIGMS - Unit V
31/33
Latching variables specify conditions that once set never change. This provides a way to start
several threads and have them wait until a signal is received from a coordinating thread. [1]
The following program creates a set of threads, but doesn't let any thread start until all the
threads are created.
import java.util.concurrent.*;
public class LatchTest
{
private static final int COUNT = 10;
private static class Worker implements Runnable
{
CountDownLatch startLatch;
CountDownLatch stopLatch;
String name;
Worker(CountDownLatch startLatch, CountDownLatch stopLatch, String name)
{
this.startLatch = startLatch;
this.stopLatch = stopLatch;
this.name = name;
}
public void run()
{
try
{
startLatch.await(); // wait until the latch has counted down to
// zero
} catch (InterruptedException ex)
{
ex.printStackTrace();
}
System.out.println("Running: " + name);stopLatch.countDown();
}
}
public static void main(String args[])
{
// CountDownLatch(int count)
// Constructs a CountDownLatch initialized with the given count.
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch stopSignal = new CountDownLatch(COUNT);
for (int i = 0; i < COUNT; i++){
7/31/2019 PROGRAMMING PARADIGMS - Unit V
32/33
new Thread(new Worker(startSignal, stopSignal, Integer.toString(i)))
.start();
}
System.out.println("Go");
startSignal.countDown();
try{
stopSignal.await();
} catch (InterruptedException ex)
{
ex.printStackTrace();
}
System.out.println("Done");
}
}
Thread and event driven programming:
The single-thread rule:
Here's the rule:
Once a Swing component has been realized, all code that might affect or depend on the state
of that component should be executed in the event-dispatching thread.
This rule might sound scary, but for many simple programs, you don't have to worry about
threads. Before we go into detail about how to write Swing code, let's define two terms:
realizedand event-dispatching thread.
Realizedmeans that the component's paint() method has been or might be called. A Swing
component that's a top-level window is realized by having one of these methods invoked on
it: setVisible(true), show(), or (this might surprise you) pack(). Once a window is realized, all
components that it contains are realized. Another way to realize a component is to add it to a
container that's already realized. You'll see examples of realizing components later.
The event-dispatching threadis the thread that executes drawing and event-handling code.
For example, the paint() and actionPerformed() methods are automatically executed in theevent-dispatching thread. Another way to execute code in the event-dispatching thread is to
use the SwingUtilitiesinvokeLater() method.
Example:
import java.awt.FlowLayout;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JFrame;import javax.swing.JLabel;
7/31/2019 PROGRAMMING PARADIGMS - Unit V
33/33
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class InvokeAndWaitDemo extends Object {
private static void print(String msg) {String name = Thread.currentThread().getName();
System.out.println(name + ": " + msg);
}
public static void main(String[] args) {
final JLabel label = new JLabel("--------");
JPanel panel = new JPanel(new FlowLayout());
panel.add(label);
JFrame f = new JFrame("InvokeAndWaitDemo");
f.setContentPane(panel);
f.setSize(300, 100);
f.setVisible(true);
try {
print("sleeping for 3 seconds");
Thread.sleep(3000);
print("creating code block for event thread");
Runnable setTextRun = new Runnable() {
public void run() {
print("about to do setText()");
label.setText("New text!");
}
};
print("about to invokeAndWait()");
SwingUtilities.invokeAndWait(setTextRun);
print("back from invokeAndWait()");
} catch (InterruptedException ix) {
print("interrupted while waiting on invokeAndWait()");
} catch (InvocationTargetException x) {
print("exception thrown from run()");
}
}
}
Top Related