Unit Iv R1
Unit Iv R1
1. Multithreading
2. Multitasking
3. Process-based multitasking
4. Thread-based multitasking
5. What is Thread
36) static void setDefaultUnc It sets the default handler invoked when
aughtExceptio a thread abruptly terminates due to an
nHandler() uncaught exception.
Life cycle of a Thread (Thread
States)
In Java, a thread always exists in any one of the following states. These states
are:
1. New
2. Active
3. Blocked / Waiting
4. Timed Waiting
5. Terminated
Active: When a thread invokes the start() method, it moves from the new state
to the active state. The active state contains two states within it: one
is runnable, and the other is running.
For example, a thread (let's say its name is A) may want to print some data
from the printer. However, at the same time, the other thread (let's say its
name is B) is using the printer to print some data. Therefore, thread A has to
wait for thread B to use the printer. Thus, thread A is in the blocked state. A
thread in the blocked state is unable to perform any execution and thus never
consume any cycle of the Central Processing Unit (CPU). Hence, we can say
that thread A remains idle until the thread scheduler reactivates thread A,
which is in the waiting or blocked state.
When the main thread invokes the join() method then, it is said that the main
thread is in the waiting state. The main thread then waits for the child threads
to complete their tasks. When the child threads complete their job, a
notification is sent to the main thread, which again moves the thread from
waiting to the active state.
If there are a lot of threads in the waiting or blocked state, then it is the duty
of the thread scheduler to determine which thread to choose and which one
to reject, and the chosen thread is then given the opportunity to run.
o When a thread has finished its job, then it exists or terminates normally.
o Abnormal termination: It occurs when some unusual events such as an
unhandled exception or segmentation fault.
The following diagram shows the different states involved in the life cycle of a
thread.
It represents the blocked state. In this state, the thread is waiting to acquire a
lock.
It represents the waiting state. A thread will go to this state when it invokes
the Object.wait() method, or Thread.join() method with no timeout. A thread in
the waiting state is waiting for another thread to complete its task.
It represents the timed waiting state. The main difference between waiting and
timed waiting is the time constraint. Waiting has no time constraint, whereas
timed waiting has the time constraint. A thread invoking the following method
reaches the timed waiting state.
o sleep
o join with timeout
o wait with timeout
o parkUntil
o parkNanos
FileName: ThreadState.java
Output:
The state of thread t1 after spawning it - NEW
The state of thread t1 after invoking the method start() on it - RUNNABLE
The state of thread t2 after spawning it - NEW
the state of thread t2 after calling the method start() on it - RUNNABLE
The state of thread t1 while it invoked the method join() on thread t2 -
TIMED_WAITING
The state of thread t2 after invoking the method sleep() on it - TIMED_WAITING
The state of thread t2 when it has completed it's execution - TERMINATED
Explanation: Whenever we spawn a new thread, that thread attains the new
state. When the method start() is invoked on a thread, the thread scheduler
moves that thread to the runnable state. Whenever the join() method is
invoked on any thread instance, the current thread executing that statement
has to wait for this thread to finish its execution, i.e., move that thread to the
terminated state. Therefore, before the final print statement is printed on the
console, the program invokes the method join() on thread t2, making the
thread t1 wait while the thread t2 finishes its execution and thus, the thread t2
get to the terminated or dead state. Thread t1 goes to the waiting state
because it is waiting for thread t2 to finish it's execution as it has invoked the
method join() on thread t2.
Thread class:
Thread class provide constructors and methods to create and perform
operations on a thread.Thread class extends Object class and implements
Runnable interface.
o Thread()
o Thread(String name)
o Thread(Runnable r)
o Thread(Runnable r,String name)
Commonly used methods of Thread class:
Runnable interface:
The Runnable interface should be implemented by any class whose instances
are intended to be executed by a thread. Runnable interface have only one
method named run().
Starting a thread:
The start() method of Thread class is used to start a newly created thread. It
performs the following tasks:
Output:
thread is running...
Output:
thread is running...
If you are not extending the Thread class, your class object would not be
treated as a thread object. So you need to explicitly create the Thread class
object. We are passing the object of your class that implements Runnable so
that your class run() method may execute.
FileName: MyThread1.java
Output:
My first thread
FileName: MyThread2.java
Output:
My new thread
Now the thread is running ...
Priority: Priority of each thread lies between 1 to 10. If a thread has a higher
priority, it means that thread has got a better chance of getting picked up by
the thread scheduler.
Time of Arrival: Suppose two threads of the same priority enter the runnable
state, then priority cannot be the factor to pick a thread from these two
threads. In such a case, arrival time of thread is considered by the thread
scheduler. A thread that arrived first gets the preference over the other
threads.
t1 0
t2 1
t3 2
t4 3
In the above table, we can see that Thread t1 has arrived first, then Thread t2,
then t3, and at last t4, and the order in which the threads will be processed is
according to the time of arrival of threads.
Hence, Thread t1 will be processed first, and Thread t4 will be processed last.
Time-slicing scheduling:
Usually, the First Come First Serve algorithm is non-preemptive, which is bad
as it may lead to infinite blocking (also known as starvation). To avoid that,
some time-slices are provided to the threads so that after some time, the
running thread has to give up the CPU. Thus, the other waiting threads also
get time to run their job.
In the above diagram, each thread is given a time slice of 2 seconds. Thus,
after 2 seconds, the first thread leaves the CPU, and the CPU is then captured
by Thread2. The same process repeats for the other threads too.
Preemptive-Priority Scheduling:
The name of the scheduling algorithm denotes that the algorithm is related to
the priority of the threads.
Suppose there are multiple threads available in the runnable state. The thread
scheduler picks that thread that has the highest priority. Since the algorithm is
also preemptive, therefore, time slices are also provided to the threads to
avoid starvation. Thus, after some time, even if the highest priority thread has
not completed its job, it has to release the CPU because of preemption.
The thread scheduler selects the thread that has the highest priority, and the
thread begins the execution of the job. If a thread is already in runnable state
and another thread (that has higher priority) reaches in the runnable state,
then the current thread is pre-empted from the processor, and the arrived
thread with higher priority gets the CPU time.
When two threads (Thread 2 and Thread 3) having the same priorities and
arrival time, the scheduling will be decided on the basis of FCFS algorithm.
Thus, the thread that arrives first gets the opportunity to execute first.
The method sleep() with the one parameter is the native method, and the
implementation of the native method is accomplished in another
programming language. The other methods having the two parameters are
not the native method. That is, its implementation is accomplished in Java. We
can access the sleep() methods with the help of the Thread class, as the
signature of the sleep() methods contain the static keyword. The native, as well
as the non-native method, throw a checked Exception. Therefore, either try-
catch block or the throws keyword can work here.
The Thread.sleep() method can be used with any thread. It means any other
thread or the main thread can invoke the sleep() method.
Parameters:
The following are the parameters used in the sleep() method.
Whenever another thread does interruption while the current thread is already
in the sleep mode, then the InterruptedException is thrown.
If the system that is executing the threads is busy, then the actual sleeping
time of the thread is generally more as compared to the time passed in
arguments. However, if the system executing the sleep() method has less load,
then the actual sleeping time of the thread is almost equal to the time passed
in the argument.
FileName: TestSleepMethod1.java
6. System.out.println(i);
7. }
8. }
9. public static void main(String args[]){
10. TestSleepMethod1 t1=new TestSleepMethod1();
11. TestSleepMethod1 t2=new TestSleepMethod1();
12.
13. t1.start();
14. t2.start();
15. }
16.}
Output:
1
1
2
2
3
3
4
4
As you know well that at a time only one thread is executed. If you sleep a
thread for the specified time, the thread scheduler picks up another thread
and so on.
Output:
0
1
2
3
4
Example of the sleep() Method in Java: When the
sleeping time is -ive
The following example throws the exception IllegalArguementException when
the time for sleeping is negative.
FileName: TestSleepMethod3.java
Output:
java.lang.IllegalArgumentException: timeout value is negative
FileName: TestCallRun1.java
Output:
running...
Problem if you direct call run() method
FileName: TestCallRun2.java
Output:
1
2
3
4
1
2
3
4
Syntax:
Syntax:
join(long mls, int nanos): When the join() method is invoked, the current
thread stops its execution and go into the wait state. The current thread
remains in the wait state until the thread on which the join() method is
invoked called is dead or the wait for the specified time frame(in milliseconds
+ nanos) is over.
Syntax:
1. public final synchronized void join(long mls, int nanos) throws InterruptedE
xception, where mls is in milliseconds.
FileName: ThreadJoinExample.java
Output:
The current thread name is: main
The current thread name is: Thread - 0
0
The current thread name is: Thread - 0
1
The current thread name is: main
The current thread name is: Thread - 1
0
The current thread name is: Thread - 1
1
The current thread name is: Thread - 2
0
The current thread name is: Thread - 2
1
Explanation: The above program shows that the second thread th2 begins
after the first thread th1 has ended, and the thread th3 starts its work after the
second thread th2 has ended or died.
The Join() Method: InterruptedException
We have learnt in the description of the join() method that whenever the
interruption of the thread occurs, it leads to the throwing of
InterruptedException. The following example shows the same.
FileName: ThreadJoinExample1.java
Output:
The exception has been caught. java.lang.InterruptedException
Filename: TestJoinMethod1.java
Output:
1
2
3
4
5
1
1
2
2
3
3
4
4
5
5
We can see in the above example, when t1 completes its task then t2 and t3
starts executing.
Output:
1
2
3
1
4
1
2
5
2
3
3
4
4
5
5
In the above example, when t1 completes its task for 1500 milliseconds(3
times), then t2 and t3 start executing.
We can also set the name of a thread directly when we create a new thread
using the constructor of the class.
Output:
Name of t1:Thread-0
Name of t2:Thread-1
After changing name of t1:Sonoo Jaiswal
running...
running...
FileName: ThreadNamingExample.java
Output:
Thread - 1: JavaTpoint1
Thread - 2: JavaTpoint2
The thread is executing....
The thread is executing....
Current Thread
The currentThread() method returns a reference of the currently executing
thread.
Output:
Thread-0
Thread-1
Output:
Priority of the thread th1 is : 5
Priority of the thread th2 is : 5
Priority of the thread th2 is : 5
Priority of the thread th1 is : 6
Priority of the thread th2 is : 3
Priority of the thread th3 is : 9
Currently Executing The Thread : main
Priority of the main thread is : 5
Priority of the main thread is : 10
We know that a thread with high priority will get preference over lower
priority threads when it comes to the execution of threads. However, there can
be other scenarios where two threads can have the same priority. All of the
processing, in order to look after the threads, is done by the Java thread
scheduler. Refer to the following example to comprehend what will happen if
two threads have the same priority.
FileName: ThreadPriorityExample1.java
Output:
Priority of the main thread is : 7
Priority of the thread th1 is : 7
Explanation: If there are two threads that have the same priority, then one
can not predict which thread will get the chance to execute first. The execution
then is dependent on the thread scheduler's algorithm (First Come First Serve,
Round-Robin, etc.)
Example of IllegalArgumentException
We know that if the value of the parameter newPriority of the method
getPriority() goes out of the range (1 to 10), then we get the
IllegalArgumentException. Let's observe the same with the help of an example.
FileName: IllegalArgumentException.java
There are many java daemon threads running automatically e.g. gc, finalizer
etc.
You can see all the detail by typing the jconsole in the command prompt. The
jconsole tool provides information about the loaded classes, memory usage,
running threads etc.
No Method Description
.
Output:
Note: If you want to make a user thread as Daemon, it must not be started otherwise
it will throw IllegalThreadStateException.
File: MyThread.java
Output:
File: WorkerThread.java
1. import java.util.concurrent.ExecutorService;
2. import java.util.concurrent.Executors;
3. class WorkerThread implements Runnable {
4. private String message;
5. public WorkerThread(String s){
6. this.message=s;
7. }
8. public void run() {
9. System.out.println(Thread.currentThread().getName()+" (Start) message =
"+message);
10. processmessage();//call processmessage method that sleeps the thread f
or 2 seconds
11. System.out.println(Thread.currentThread().getName()+" (End)");//prints th
read name
12. }
13. private void processmessage() {
14. try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTr
ace(); }
15. }
16.}
File: TestThreadPool.java
Output:
FileName: ThreadPoolExample.java
Deadlock: It is a known fact that deadlock can come in any program that
involves multithreading, and a thread pool introduces another scenario of
deadlock. Consider a scenario where all the threads that are executing are
waiting for the results from the threads that are blocked and waiting in the
queue because of the non-availability of threads for the execution.
Points to Remember
Do not queue the tasks that are concurrently waiting for the results obtained
from the other tasks. It may lead to a deadlock situation, as explained above.
Care must be taken whenever threads are used for the operation that is long-
lived. It may result in the waiting of thread forever and will finally lead to the
leakage of the resource.
In the end, the thread pool has to be ended explicitly. If it does not happen,
then the program continues to execute, and it never ends. Invoke the
shutdown() method on the thread pool to terminate the executor. Note that if
someone tries to send another task to the executor after shutdown, it will
throw a RejectedExecutionException.
One needs to understand the tasks to effectively tune the thread pool. If the
given tasks are contrasting, then one should look for pools for executing
different varieties of tasks so that one can properly tune them.
To reduce the probability of running JVM out of memory, one can control the
maximum threads that can run in JVM. The thread pool cannot create new
threads after it has reached the maximum limit.
A thread pool can use the same used thread if the thread has finished its
execution. Thus, the time and resources used for the creation of a new thread
are saved.
Conclusion
A thread pool is a very handy tool for organizing applications, especially on
the server-side. Concept-wise, a thread pool is very easy to comprehend.
However, one may have to look at a lot of issues when dealing with a thread
pool. It is because the thread pool comes with some risks involved it (risks are
discussed above).
ThreadGroup in Java
Java provides a convenient way to group multiple threads in a single object. In
such a way, we can suspend, resume or interrupt a group of threads by a
single method call.
A thread is allowed to access information about its own thread group, but it
cannot access the information about its thread group's parent thread group or
any other thread groups.
No Constructor Description
.
17) void setMaxPriority(int pri) This method sets the maximum prio
group.
Now all 3 threads belong to one group. Here, tg1 is the thread group name,
MyRunnable is the class that implements Runnable interface and "one", "two"
and "three" are the thread names.
1. Thread.currentThread().getThreadGroup().interrupt();
ThreadGroup Example
File: ThreadGroupDemo.java
Output:
one
two
three
Thread Group Name: Parent ThreadGroup
java.lang.ThreadGroup[name=Parent ThreadGroup,maxpri=10]
FileName: ActiveCountExample.java
Output:
Starting the first
Starting the second
The total number of active threads are: 2
FileName: ActiveGroupCountExample.java
Output:
Starting the first
Starting the second
The total number of active thread groups are: 1
the second thread has finished executing
the first thread has finished executing
FileName: DestroyExample.java
1. // Code illustrating the destroy() method
2.
3. // import statement
4. import java.lang.*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
10.ThreadNew(String tName, ThreadGroup tgrp)
11.{
12.super(tgrp, tName);
13.start();
14.}
15.
16.// overriding the run() method
17.public void run()
18.{
19.
20.for (int j = 0; j < 100; j++)
21.{
22.try
23.{
24.Thread.sleep(5);
25.}
26.catch (InterruptedException e)
27.{
28.System.out.println("The exception has been encountered " + e);
29.}
30.
31.}
32.
33.System.out.println(Thread.currentThread().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
37.public class DestroyExample
38.{
39.// main method
40.public static void main(String argvs[]) throws SecurityException, InterruptedE
xception
41.{
42.// creating the thread group
43.ThreadGroup tg = new ThreadGroup("the parent group");
44.
45.ThreadGroup tg1 = new ThreadGroup(tg, "the child group");
46.
47.ThreadNew th1 = new ThreadNew("the first", tg);
48.System.out.println("Starting the first");
49.
50.ThreadNew th2 = new ThreadNew("the second", tg);
51.System.out.println("Starting the second");
52.
53.// waiting until the other threads has been finished
54.th1.join();
55.th2.join();
56.
57.// destroying the child thread group
58.tg1.destroy();
59.System.out.println(tg1.getName() + " is destroyed.");
60.
61.// destroying the parent thread group
62.tg.destroy();
63.System.out.println(tg.getName() + " is destroyed.");
64.}
65.}
Output:
Starting the first
Starting the second
the first thread has finished executing
the second thread has finished executing
the child group is destroyed.
the parent group is destroyed.
FileName: EnumerateExample.java
Output:
Starting the first
Starting the second
Thread the first is found.
Thread the second is found.
the first thread has finished executing
the second thread has finished executing
Thread Pool Methods Example: int
getMaxPriority()
The following code shows the working of the getMaxPriority() method.
FileName: GetMaxPriorityExample.java
Output:
Starting the first
Starting the second
The maximum priority of the parent ThreadGroup: 10
the first thread has finished executing
the second thread has finished executing
FileName: GetParentExample.java
Output:
Starting the first
Starting the second
The ParentThreadGroup for the parent group is main
The ParentThreadGroup for the child group is the parent group
the first thread has finished executing
the second thread has finished executing
Thread Pool Methods Example: void
interrupt()
The following program illustrates how one can use the interrupt() method.
FileName: InterruptExample.java
Output:
Starting the first
Starting the second
The exception has been encountered java.lang.InterruptedException: sleep
interrupted
The exception has been encountered java.lang.InterruptedException: sleep
interrupted
the second thread has finished executing
the first thread has finished executing
FileName: IsDaemonExample.java
Output:
Starting the first
Starting the second
The group is not a daemon group.
the second thread has finished executing
the first thread has finished executing
Thread Pool Methods Example: boolean
isDestroyed()
The following program illustrates how one can use the isDestroyed() method.
FileName: IsDestroyedExample.java
Output:
Starting the first
Starting the second
The group has not been destroyed.
the first thread has finished executing
the second thread has finished executing
Synchronization in Java
Synchronization in Java is the capability to control the access of multiple
threads to any shared resource.
Java Synchronization is better option where we want to allow only one thread
to access the shared resource.
1. Process Synchronization
2. Thread Synchronization
Thread Synchronization
There are two types of thread synchronization mutual exclusive and inter-
thread communication.
1. Mutual Exclusive
1. Synchronized method.
2. Synchronized block.
3. Static synchronization.
2. Cooperation (Inter-thread communication in java)
Mutual Exclusive
Mutual Exclusive helps keep threads from interfering with one another while
sharing data. It can be achieved by using the following three ways:
TestSynchronization1.java
1. class Table{
2. void printTable(int n){//method not synchronized
3. for(int i=1;i<=5;i++){
4. System.out.println(n*i);
5. try{
6. Thread.sleep(400);
7. }catch(Exception e){System.out.println(e);}
8. }
9.
10. }
11.}
12.
13.class MyThread1 extends Thread{
14.Table t;
15.MyThread1(Table t){
16.this.t=t;
17.}
18.public void run(){
19.t.printTable(5);
20.}
21.
22.}
23.class MyThread2 extends Thread{
24.Table t;
25.MyThread2(Table t){
26.this.t=t;
27.}
28.public void run(){
29.t.printTable(100);
30.}
31.}
32.
33.class TestSynchronization1{
34.public static void main(String args[]){
35.Table obj = new Table();//only one object
36.MyThread1 t1=new MyThread1(obj);
37.MyThread2 t2=new MyThread2(obj);
38.t1.start();
39.t2.start();
40.}
41.}
Output:
5
100
10
200
15
300
20
400
25
500
Java Synchronized Method
If you declare any method as synchronized, it is known as synchronized
method.
TestSynchronization2.java
Output:
5
10
15
20
25
100
200
300
400
500
Example of synchronized method by
using annonymous class
In this program, we have created the two threads by using the anonymous
class, so less coding is required.
TestSynchronization3.java
Output:
5
10
15
20
25
100
200
300
400
500
If we put all the codes of the method in the synchronized block, it will work
same as the synchronized method.
Points to Remember
o Synchronized block is used to lock an object for any shared resource.
o Scope of synchronized block is smaller than the method.
o A Java synchronized block doesn't allow more than one JVM, to provide
access control to a shared resource.
o The system performance may degrade because of the slower working of
synchronized keyword.
o Java synchronized block is more efficient than Java synchronized
method.
Syntax
TestSynchronizedBlock1.java
1. class Table
2. {
3. void printTable(int n){
4. synchronized(this){//synchronized block
5. for(int i=1;i<=5;i++){
6. System.out.println(n*i);
7. try{
8. Thread.sleep(400);
9. }catch(Exception e){System.out.println(e);}
10. }
11. }
12. }//end of the method
13.}
14.
15.class MyThread1 extends Thread{
16.Table t;
17.MyThread1(Table t){
18.this.t=t;
19.}
20.public void run(){
21.t.printTable(5);
22.}
23.
24.}
25.class MyThread2 extends Thread{
26.Table t;
27.MyThread2(Table t){
28.this.t=t;
29.}
30.public void run(){
31.t.printTable(100);
32.}
33.}
34.
35.public class TestSynchronizedBlock1{
36.public static void main(String args[]){
37.Table obj = new Table();//only one object
38.MyThread1 t1=new MyThread1(obj);
39.MyThread2 t2=new MyThread2(obj);
40.t1.start();
41.t2.start();
42.}
43.}
Output:
5
10
15
20
25
100
200
300
400
500
1. // A Sender class
2. class Sender
3. {
4. public void SenderMsg(String msg)
5. {
6. System.out.println("\nSending a Message: " + msg);
7. try
8. {
9. Thread.sleep(800);
10. }
11. catch (Exception e)
12. {
13. System.out.println("Thread interrupted.");
14. }
15. System.out.println("\n" +msg+ "Sent");
16. }
17.}
18.// A Sender class for sending a message using Threads
19.class SenderWThreads extends Thread
20.{
21. private String msg;
22. Sender sd;
23.
24. // Receiver method to receive a message object and a message to be sent
25. SenderWThreads(String m, Sender obj)
26. {
27. msg = m;
28. sd = obj;
29. }
30.
31. public void run()
32. {
33. // Checks that only one thread sends a message at a time.
34. synchronized(sd)
35. {
36. // synchronizing the sender object
37. sd.SenderMsg(msg);
38. }
39. }
40.}
41.// Driver Code
42.public class ShynchronizedMultithreading
43.{
44. public static void main(String args[])
45. {
46. Sender sender = new Sender();
47. SenderWThreads sender1 = new SenderWThreads( "Hola " , sender);
48.SenderWThreads sender2 = new SenderWThreads( "Welcome to Javatpoint w
ebsite ", sender);
49.
50. // Start two threads of SenderWThreads type
51. sender1.start();
52. sender2.start();
53.
54. // wait for threads to end
55. try
56. {
57. sender1.join();
58. sender2.join();
59. }
60. catch(Exception e)
61. {
62. System.out.println("Interrupted");
63. }
64. }
65.}
Output:
Sending a Message: Hola
Hola Sent
Sending a Message: Welcome to Javatpoint website
Welcome to Javatpoint website Sent
Static Synchronization
If you make any static method as synchronized, the lock will be on the class
not on object.
Problem without static synchronization
Suppose there are two objects of a shared class (e.g. Table) named object1
and object2. In case of synchronized method and synchronized block there
cannot be interference between t1 and t2 or t3 and t4 because t1 and t2 both
refers to a common object that have a single lock. But there can be
interference between t1 and t3 or t2 and t4 because t1 acquires another lock
and t3 acquires another lock. We don't want interference between t1 and t3 or
t2 and t4. Static synchronization solves this problem.
TestSynchronization4.java
1. class Table
2. {
3. synchronized static void printTable(int n){
4. for(int i=1;i<=10;i++){
5. System.out.println(n*i);
6. try{
7. Thread.sleep(400);
8. }catch(Exception e){}
9. }
10. }
11.}
12.class MyThread1 extends Thread{
13.public void run(){
14.Table.printTable(1);
15.}
16.}
17.class MyThread2 extends Thread{
18.public void run(){
19.Table.printTable(10);
20.}
21.}
22.class MyThread3 extends Thread{
23.public void run(){
24.Table.printTable(100);
25.}
26.}
27.class MyThread4 extends Thread{
28.public void run(){
29.Table.printTable(1000);
30.}
31.}
32.public class TestSynchronization4{
33.public static void main(String t[]){
34.MyThread1 t1=new MyThread1();
35.MyThread2 t2=new MyThread2();
36.MyThread3 t3=new MyThread3();
37.MyThread4 t4=new MyThread4();
38.t1.start();
39.t2.start();
40.t3.start();
41.t4.start();
42.}
43.}
Test it Now
Output:
1
2
3
4
5
6
7
8
9
10
10
20
30
40
50
60
70
80
90
100
100
200
300
400
500
600
700
800
900
1000
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
TestSynchronization5.javaHello
1. class Table{
2.
3. synchronized static void printTable(int n){
4. for(int i=1;i<=10;i++){
5. System.out.println(n*i);
6. try{
7. Thread.sleep(400);
8. }catch(Exception e){}
9. }
10. }
11.}
12.
13.public class TestSynchronization5 {
14.public static void main(String[] args) {
15.
16. Thread t1=new Thread(){
17. public void run(){
18. Table.printTable(1);
19. }
20. };
21.
22. Thread t2=new Thread(){
23. public void run(){
24. Table.printTable(10);
25. }
26. };
27.
28. Thread t3=new Thread(){
29. public void run(){
30. Table.printTable(100);
31. }
32. };
33.
34. Thread t4=new Thread(){
35. public void run(){
36. Table.printTable(1000);
37. }
38. };
39. t1.start();
40. t2.start();
41. t3.start();
42. t4.start();
43.
44.}
45.}
Test it Now
Output:
1
2
3
4
5
6
7
8
9
10
10
20
30
40
50
60
70
80
90
100
100
200
300
400
500
600
700
800
900
1000
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
Output:
Thread 1: locked resource 1
Thread 2: locked resource 2
More Complicated Deadlocks
A deadlock may also include more than two threads. The reason is that it can
be difficult to detect a deadlock. Here is an example in which four threads
have deadlocked:
Thread 1 waits for thread 2, thread 2 waits for thread 3, thread 3 waits for
thread 4, and thread 4 waits for thread 1.
DeadlockSolved.java
In the above code, class DeadlockSolved solves the deadlock kind of situation.
It will help in avoiding deadlocks, and if encountered, in resolving them.
Inter-thread Communication in
Java
Inter-thread communication or Co-operation is all about allowing
synchronized threads to communicate with each other.
1) wait() method
The wait() method causes current thread to release the lock and wait until
either another thread invokes the notify() method or the notifyAll() method for
this object, or a specified amount of time has elapsed.
The current thread must own this object's monitor, so it must be called from
the synchronized method only otherwise it will throw exception.
Method Description
2) notify() method
The notify() method wakes up a single thread that is waiting on this object's
monitor. If any threads are waiting on this object, one of them is chosen to be
awakened. The choice is arbitrary and occurs at the discretion of the
implementation.
Syntax:
3) notifyAll() method
Wakes up all threads that are waiting on this object's monitor.
Syntax:
wait() sleep()
The wait() method releases the lock. The sleep() method doesn't release the
Test.java
1. class Customer{
2. int amount=10000;
3.
4. synchronized void withdraw(int amount){
5. System.out.println("going to withdraw...");
6.
7. if(this.amount<amount){
8. System.out.println("Less balance; waiting for deposit...");
9. try{wait();}catch(Exception e){}
10.}
11.this.amount-=amount;
12.System.out.println("withdraw completed...");
13.}
14.
15.synchronized void deposit(int amount){
16.System.out.println("going to deposit...");
17.this.amount+=amount;
18.System.out.println("deposit completed... ");
19.notify();
20.}
21.}
22.
23.class Test{
24.public static void main(String args[]){
25.final Customer c=new Customer();
26.new Thread(){
27.public void run(){c.withdraw(15000);}
28.}.start();
29.new Thread(){
30.public void run(){c.deposit(10000);}
31.}.start();
32.
33.}}
Output:
going to withdraw...
Less balance; waiting for deposit...
going to deposit...
deposit completed...
withdraw completed
Interrupting a Thread:
If any thread is in sleeping or waiting state (i.e. sleep() or wait() is invoked),
calling the interrupt() method on the thread, breaks out the sleeping or
waiting state throwing InterruptedException. If the thread is not in the
sleeping or waiting state, calling the interrupt() method performs normal
behaviour and doesn't interrupt the thread but sets the interrupt flag to true.
Let's first see the methods provided by the Thread class for thread
interruption.
TestInterruptingThread1.java
Output:
Exception in thread-0
java.lang.RuntimeException: Thread interrupted...
java.lang.InterruptedException: sleep interrupted
at A.run(A.java:7)
TestInterruptingThread2.java
Output:
Exception handled
java.lang.InterruptedException: sleep interrupted
thread is running...
TestInterruptingThread3.java
Output:
1
2
3
4
5
TestInterruptingThread4.java
Output:
Code for interrupted thread
code for normal thread
code for normal thread
code for normal thread