Multithreading in Java, is the mechanism of executing different parts of a program simultaneously.
Suppose, in a normal program, we are in one method and calling another method then the control goes to the called method, executes the statements in that method and comes back to calling the method.
As long as the control executes the method, the statements after the method call are not executed in the calling method. Those statements are executed only after the control comes back from called method.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
void one() { two(); Somestatements; } void two() { Somecode; } |
In the above example, when method two() is called from method one(), then the control goes to the definition of two() and executes ‘Somecode’. As long as that code is executed the one() will wait.
Once the execution of two() is complete, the control comes back to one() to execute ‘Somestatements’. This is what happens in a normal (single-threaded) program.
If we want to execute both the parts (‘Somecode’ and ‘Somestatements’) at a time (in parallel) then we should approach multi threading.
Java Multi Threading Example & Suitable Examples
- The ‘multithreading’ can be seen at many places in our computers.
- Suppose we are playing a game and at the same time listening to some music.
- In that case both the applications (processes) are placed in the process queue and the processor will work on them in a time sharing manner.
- For a normal user, it looks like both the things (game and music) are running simultaneously.
- In fact, the processor works on each process one after another (spending very small amounts of time on each) where the small time cannot be identified by us.
Suppose the processor started working on a song (some music) and spent 1 millisecond (supposed time). In that one millisecond, the processor takes data from the song file and gives to the audio device.
The data gathered by the processor in 1 millisecond will be played by 1 minute (suppose). In the meanwhile (next millisecond), the processor will work on other processes (say game) and works on it.
- Maybe the processor will work on the game for 1 millisecond. In that 1 millisecond, the processor will take user inputs (through the keyboard, mouse, joystick, etc) and performs the required operation.
- Again in the third millisecond, the processor will work on the song. This way the processor keeps working on both parallelly.
- If we have more processes then the processor will work on all those processes simultaneously (from a user point of view) and one by one in a cycle (inside). All of this mechanism is known as process-based multi-tasking.
Similar to this, we can divide our program into different processes (threads) and execute all the threads simultaneously. It means it looks like simultaneous to a normal user but the system will keep working on them on a time-sliced basis.
At one time the system works on one process/part/thread only and that small amount of time is generally not recognized by the user. This mechanism is known as thread based multitasking.
Process-based multitasking is controlled by operating system and thread based multi-tasking can be controlled by our program. This thread based multi-tasking is also known as Multithreading.
Suppose we are writing a program for a car race and multiple cars should be running simultaneously (in parallel).
- Let us assume each car is an object.
- If we write the program in a single thread, we can move only one car at one time.
- When a car is moving other cars should stand unmoved.
- This is not acceptable to be a race.
- We should see all the cars moving in parallel.
To get this effect, we should approach multi-threading where each car is moved by one thread and all the threads will run in parallel irrespective of other threads.
In Java, the class Thread helps to achieve multi threading. When we want to provide multi threading features to a class, then we can inherit Thread class to that class.
Example:
1 2 3 4 5 |
class Alpha extends Thread { } |
When we create an object of the above class Alpha, that object will have Thread facilities. Once such an object is started ( using the method start() ) the control creates a separate branch and executes the code in the Alpha class.
Example:
1 2 3 |
Alpha a=new Alpha(); a.start(); |
The start method creates a new branch and starts run() method automatically. We should define the run() method in the corresponding class (Alpha, in our example).
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Alpha extends Thread { public void run() { Somecode; } } |
Suppose, in the following program we have created an object of class Alpha and started it. When the thread has started the run() method of the class Alpha is executed in a separate branch and at the same time, the remaining code in main() method is executed.
The code in run() prints alphabets (A B C D ….. Y Z) and the code in main() prints numbers (1 2 3 ……. 24 25). As both the codes execute simultaneously we can see both outputs printed together (mixed).
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
class Alpha extends Thread { public void run() { for(int i=65; i<=90; i++) { System.out.print((char)i+" "); } } } class Multi { public static void main(String arg[]) { Alpha a=new Alpha(); a.start(); for(int i=1; i<=25; i++) { System.out.print(i+" "); } } } |
Output (probable):
1 |
A 1 2 B C 3 4 D 5 E 6 F 7 8 9 G H 10 11 I J 12 13 14 K L M 15 16 17 N O P 18 19 20 21 Q R S T U V 22 23 W 24 25 X Y Z |
The output may vary from one execution to another execution as the amount of time spent by the system on each thread may vary from time to time. This time depends on the number of processes running currently, RAM capacity, processor speed, etc.
In the above example, a is referring to a thread object and we can create any number of such objects. Is When we create a thread object but not yet started, then we say that the thread is in the READY state. Once the thread starts we call that the thread is in RUNNING state.
- Sometimes a thread should wait (suspend its operations temporarily) up to some other thread completes some task.
- Such a period is known as WAITING state.
- The WAITING state is part of the RUNNING state.
When a thread completes its execution (completes the corresponding run() method), we say that the thread is in DEAD state.
Methods In Thread Operations
- isAlive() to know whether a thread is in running state or not. It checks whether the invoking thread is running/active/alive. If so, It returns true otherwise it returns false.
- wait(): It makes a thread wait till same other thread completes its work and notify it. If no other thread notifies then the waiting state only indefinitely.
- wait(long milliseconds): This method waits for a maximum of the specified number of milliseconds for a notification from other threads. If no notification comes within the time then the waiting thread automatically resumes.
- wait(Milli, Nanos): This is similar to the previous method wait(long milliseconds) but it can take nanoseconds also as waiting time.
- join(): join() to make a thread wait until some other thread completes its execution.
It is a method that makes the parent thread wait until another thread completes its execution and joins the current thread.
In the following example, the thread in which method( ) is executed is the current thread from the current thread another thread (branch) is started so the code of the branch (another thread) and statement 1 and statement 2 of the current thread are executed in parallel.
Statement 3 and statement 4 of current thread are executed only after the branch thread completes the execution.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
method( ) { branch.start(); statement 1; statement 2; try { branch.join(); } Catch(InterruptedException ie) { } statement 3; statement 4; } join( ) as three overloaded methods. join( ) – waits for indefinitely. join(millis) – waits a maximum of the specified amount of time. join(millis,nanos) – waits a maximum of the specified amount of time. setName() to change the name of a thread setPriority() to change the priority of a thread getName() to know the name of a thread getPriority() to know the priority of a thread sleep() to suspend the operation of a thread for the specified amount of time |
Example using setPriority():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
class AAA extends Thread { public void run() { System.out.println("thread AAA"); for(int i=0;i<20;i+=2) { System.out.println("even no"+i); } System.out.println("thread AAA ends"); } } class BBB extends Thread { public void run() { System.out.println("thread BBB"); for(int i=1;i<20;i+=2) { System.out.println("odd no"+i ); } System.out.println("thread BBB ends"); } } class CCC extends Thread { public void run() { int c=0; System.out.println("thread CCC"); for(int i=2;i<30;i+=1) { c=0; for(int j=1;j<=i;j+=1) { if(i%j==0) c++; } if(c==2) System.out.println("prime no"+i ); } System.out.println("thread AAA ends"); } } class ThreadPriority { public static void main(String args[]) { BBB b=new BBB(); AAA a=new AAA(); CCC c=new CCC(); a.setPriority(1); b.setPriority(10); c.setPriority(5); a.start(); b.start(); c.start(); } } |
Output: (It may vary for different compilers)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
ODD THREAD BBB odd no1 odd no3 odd no5 odd no7 odd no9 odd no11 odd no13 odd no15 odd no17 odd no19 ODD THREAD BBB ends PRIME THREAD CCC prime no2 prime no3 prime no5 prime no7 prime no11 prime no13 prime no17 prime no19 prime no23 prime no29 PRIME THREAD CCC ends EVEN THREAD BBB even no0 even no2 even no4 even no6 even no8 even no10 even no12 even no14 even no16 even no18 EVEN THREAD BBB ends |
Output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
thread AAA thread CCC thread BBB prime no2 even no0 even no2 prime no3 odd no1 prime no5 even no4 prime no7 odd no3 prime no11 even no6 prime no13 prime no17 odd no5 prime no19 even no8 prime no23 prime no29 thread CCC ends odd no7 odd no9 odd no11 even no10 odd no13 even no12 odd no15 even no14 even no16 even no18 thread AAA ends odd no17 odd no19 thread BBB ends |
Example Program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
import java.util.*; import java.lang.*; class even extends Thread { public void run() { System.out.println("even numbers are"); for(int i=0;i<=10;i=i+2) { System.out.println(i); try { Thread.sleep(100); } catch(InterruptedException ie) { } } } } class odd extends Thread { public void run() { System.out.println("odd numbers are"); for(int i=1;i<+10;i=i+2) { System.out.println("\t\t\t"+i); try { Thread.sleep(100); } catch(InterruptedException ie) { } } } } class mainth { public static void main(String arg[]) { even e=new even(); odd o=new odd(); e.start(); o.start(); } } |