Unit 4
Unit 4
Multithreading in Java
1. Multithreading
2. Multitasking
3. Process-based multitasking
4. Thread-based multitasking
5. What is Thread
Multitasking
Multitasking is a process of executing multiple tasks simultaneously. We use
multitasking to utilize the CPU. Multitasking can be achieved in two ways:
Thread States:
1. New
2. Runnable
3. Running
4. Blocked (Non-runnable state)
5. Dead
In simpler terms, Thread object is created but it cannot execute any program statement
because it is not in an execution state of the thread. Only start() method can be called
on a new thread; otherwise, an IllegalThreadStateException will be thrown.
Runnable State
The second phase of a new-born thread is the execution phase. When the start()
method is called on a the new instance of a thread, it enters into a runnable state.
In the runnable state, thread is ready for execution and is waiting for availability of the
processor (CPU time). There are many threads that are ready for execution, they all are
waiting in a queue (line).
If all threads have equal priority, a time slot is assigned for each thread execution on the
basis of first-come, first-serve manner by CPU. The process of allocating time to threads
is known as time slicing. A thread can come into runnable state from running, waiting,
or new states.
Running State
Running means Processor (CPU) has allocated time slot to thread for its execution.
When thread scheduler selects a thread from the runnable state for execution, it goes
into running state. Look at the above figure.
In running state, processor gives its time to the thread for execution and executes its run
method. It is the state where thread performs its actual functions. A thread can come
into running state only from runnable state.
A running thread may give up its control in any one of the following situations and can
enter into the blocked state.
1. When sleep() method is invoked on a thread to sleep for specified time period, the
thread is out of queue during this time period. The thread again reenters into the
runnable state as soon as this time period is elapsed.
2. When a thread is suspended using suspend() method for some time in order to satisfy
some conditions. A suspended thread can be revived by using resume() method.
3. When wait() method is called on a thread to wait for some time. The thread in wait state
can be run again using notify() or notifyAll() method.
Blocked State
A thread is considered to be in the blocked state when it is suspended, sleeping, or
waiting for some time in order to satisfy some condition.
Dead State
A thread dies or moves into dead state automatically when its run() method completes
the execution of statements. That is, a thread is terminated or dead when a thread
comes out of run() method. A thread can also be dead when the stop() method is called.
During the life cycle of thread in Java, a thread moves from one state to another state in
a variety of ways. This is because in multithreading environment, when multiple threads
are executing, only one thread can use CPU at a time.
All other threads live in some other states, either waiting for their turn on CPU or waiting
for satisfying some conditions. Therefore, a thread is always in any of the five states.
1. /* Thread 1 */
2. class Thread1 extends Thread
3. {
4.
5. public void run()
6. {
7. System.out.println("Thread 1");
8. System.out.println("i in Thread 1 ");
9. for (int i = 1; i <= 5; i++)
10. {
11. System.out.println("i = " + i);
12. try
13. {
14. Thread.sleep(1000);
15. }
16. catch (InterruptedException e)
17. {
18. e.printStackTrace();
19. }
20. }
21. System.out.println("Thread 1 Completed.");
22. }
23. }
24.
25. /* Thread 2 */
26. class Thread2 extends Thread
27. {
28. public void run()
29. {
30. System.out.println("Thread 2");
31. System.out.println("i in Thread 2 ");
32. for (int i = 1; i <= 5; i++)
33. {
34. System.out.println("i = " + i);
35. }
36. System.out.println("Thread 2 Completed.");
37. }
38. }
39.
40. /* Driver code */
41. public class ThreadDemo
42. {
43. public static void main(String[] args) {
44. // life cycle of Thread
45. // Thread's New State
46. Thread1 t1 = new Thread1();
47. Thread2 t2 = new Thread2();
48. // Both the above threads are in runnable state
49. // Running state of Thread1 and Thread2
50. t1.start();
51. // Move control to another thread
52. t2.yield();
53. // Blocked State Thread1
54. try
55. {
56. t1.sleep(1000);
57. }
58. catch (InterruptedException e)
59. {
60. e.printStackTrace();
61. }
62. t2.start();
63. System.out.println("Main Thread End");
64. }
65. }
Output:
Thread 1
i in Thread 1
i = 1
Main Thread End
Thread 2
i in Thread 2
i = 1
i = 2
i = 3
i = 4
i = 5
Thread 2 Completed.
i = 2
i = 3
i = 4
i = 5
Thread 1 Completed.
Thread Priority:
Output:
Synchronization, :
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.
Types of Synchronization
There are two types of synchronization
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
When a thread invokes a synchronized method, it automatically acquires the lock for
that object and releases it when the thread completes its task.
TestSynchronization2.java
Output:
5
10
15
20
25
100
200
300
400
500
TestSynchronization3.java
Output:
5
10
15
20
25
100
200
300
400
500
1. Read-modify-write
2. Check-then-act
The read-modify-write patterns signify that more than one thread first read the
variable, then alter the given value and write it back to that variable. Let's have a look at
the following code snippet.
RaceConditionProgram.java
Output:
Inter-thread Communication –:
o wait()
o notify()
o notifyAll()
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
public final void wait(long timeout)throws It waits for the specified amount of
InterruptedException time.
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:
Syntax:
wait() sleep()
The wait() method releases the lock. The sleep() method doesn't release the lock.
It should be notified by notify() or notifyAll() methods After the specified amount of time, sleep is completed.
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
Syntax
1. public final void suspend()
Return
This method does not return any value.
Exception
SecurityException: If the current thread cannot modify the thread.
Example
1. public class JavaSuspendExp extends Thread
2. {
3. public void run()
4. {
5. for(int i=1; i<5; i++)
6. {
7. try
8. {
9. // thread to sleep for 500 milliseconds
10. sleep(500);
11. System.out.println(Thread.currentThread().getName());
12. }catch(InterruptedException e){System.out.println(e);}
13. System.out.println(i);
14. }
15. }
16. public static void main(String args[])
17. {
18. // creating three threads
19. JavaSuspendExp t1=new JavaSuspendExp ();
20. JavaSuspendExp t2=new JavaSuspendExp ();
21. JavaSuspendExp t3=new JavaSuspendExp ();
22. // call run() method
23. t1.start();
24. t2.start();
25. // suspend t2 thread
26. t2.suspend();
27. // call run() method
28. t3.start();
29. }
30. }
Test it Now
Output:
Thread-0
1
Thread-2
1
Thread-0
2
Thread-2
2
Thread-0
3
Thread-2
3
Thread-0
4
Thread-2
4
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.
o Runnable: A thread, that is ready to run is then moved to the runnable state. In the
runnable state, the thread may be running or may be ready to run at any given instant of
time. It is the duty of the thread scheduler to provide the thread time to run, i.e., moving
the thread the running state.
A program implementing multithreading acquires a fixed slice of time to each individual
thread.
o Running: When the thread gets the CPU, it moves from the runnable to the running
state. Generally, the most common change in the state of a thread is from runnable to
running and again back to runnable.
Blocked or Waiting: Whenever a thread is inactive for a span of time (not permanently)
then, either the thread is in the blocked state or is in the waiting state.
Timed Waiting: Sometimes, waiting for leads to starvation. For example, a thread (its
name is A) has entered the critical section of a code and is not willing to leave that
critical section. In such a scenario, another thread (its name is B) has to wait forever,
which leads to starvation. To avoid such scenario, a timed waiting state is given to
thread B. Thus, thread lies in the waiting state for a specific span of time, and not
forever. A real example of timed waiting is when we invoke the sleep() method on a
specific thread. The sleep() method puts the thread in the timed wait state. After the
time runs out, the thread wakes up and start its execution from when it has left earlier.
Terminated: A thread reaches the termination state because of the following reasons:
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.
A terminated thread means the thread is no more in the system. In other words, the
thread is dead, and there is no way one can respawn (active after kill) the dead thread.
The following diagram shows the different states involved in the life cycle of a thread.
It represents the runnable state.It means a thread is waiting in the queue to run.
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
It represents the final state of a thread that is terminated or dead. A terminated thread
means it has completed its execution.
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.
Commonly used Constructors of Thread class:
o Thread()
o Thread(String name)
o Thread(Runnable r)
o Thread(Runnable r,String name)
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...
2) Java Thread Example by implementing Runnable interface
FileName: Multi3.java
Output:
thread is running...