Let's see the important differences
between wait and sleep methods.
wait()
|
sleep()
|
wait() method releases the lock
|
sleep() method doesn't release the
lock.
|
is the method of Object class
|
is the method of Thread class
|
is the non-static method
|
is the static method
|
is the non-static method
|
is the static method
|
should be notified by notify() or
notifyAll() methods
|
after the specified amount of
time, sleep is completed.
|
Example of inter thread
communication in java
Let's see the simple example of
inter thread communication.
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.
|
The 3 methods provided by the Thread class for interrupting a thread
·
public void interrupt()
·
public static boolean interrupted()
·
public boolean isInterrupted()
|
Example of interrupting a thread that stops working
In this example, after interrupting
the thread, we are propagating it, so it will stop working. If we don't want
to stop the thread, we can handle it where sleep() or wait() method is
invoked. Let's first see the example where we are propagating the exception.
|
1.
class TestInterruptingThread1 extends Thread{
2.
public void run(){
3.
try{
4.
Thread.sleep(1000);
5.
System.out.println("task");
6.
}catch(InterruptedException e){
7.
throw new RuntimeException("Thread interrupted..."+e);
8.
}
9.
10. }
11.
12. public static void main(String args[]){
13. TestInterruptingThread1 t1=new TestInterruptingThread1();
14. t1.start();
15. try{
16. t1.interrupt();
17. }catch(Exception e){System.out.println("Exception handled "+e);}
18.
19. }
20. }
Output:Exception in thread-0
java.lang.RuntimeException: Thread interrupted...
java.lang.InterruptedException: sleep interrupted
at A.run(A.java:7)
Example of interrupting a thread that doesn't stop working
In this example, after interrupting
the thread, we handle the exception, so it will break out the sleeping but
will not stop working.
|
1.
class TestInterruptingThread2 extends Thread{
2.
public void run(){
3.
try{
4.
Thread.sleep(1000);
5.
System.out.println("task");
6.
}catch(InterruptedException e){
7.
System.out.println("Exception handled "+e);
8.
}
9.
System.out.println("thread is running...");
10. }
11.
12. public static void main(String args[]){
13. TestInterruptingThread2 t1=new TestInterruptingThread2();
14. t1.start();
15.
16. t1.interrupt();
17.
18. }
19. }
Output:Exception handled
java.lang.InterruptedException: sleep interrupted
thread is running...
Example of interrupting thread that behaves normally
If thread is not in sleeping or
waiting state, calling the interrupt() method sets the interrupted flag to
true that can be used to stop the thread by the java programmer later.
|
1.
class TestInterruptingThread3 extends Thread{
2.
3.
public void run(){
4.
for(int i=1;i<=5;i++)
5.
System.out.println(i);
6.
}
7.
8.
public static void main(String args[]){
9.
TestInterruptingThread3 t1=new TestInterruptingThread3();
10. t1.start();
11.
12. t1.interrupt();
13.
14. }
15. }
Output:1
2
3
4
5
What about isInterrupted and interrupted method?
The isInterrupted() method returns
the interrupted flag either true or false. The static interrupted() method
returns the interrupted flag afterthat it sets the flag to false if it is
true.
|
1.
public class TestInterruptingThread4 extends Thread{
2.
3.
public void run(){
4.
for(int i=1;i<=2;i++){
5.
if(Thread.interrupted()){
6.
System.out.println("code for interrupted thread");
7.
}
8.
else{
9.
System.out.println("code for normal thread");
10. }
11.
12. }//end of for loop
13. }
14.
15. public static void main(String args[]){
16.
17. TestInterruptingThread4 t1=new TestInterruptingThread4();
18. TestInterruptingThread4 t2=new TestInterruptingThread4();
19.
20. t1.start();
21. t1.interrupt();
22.
23. t2.start();
24.
25. }
26. }
Output:Code for interrupted thread
code for normal thread
code for normal thread
code for normal thread
Reentrant Monitor in Java
According
to Sun Microsystems, Java monitors are reentrant means java thread can
reuse the same monitor for different synchronized methods if method is called
from the method.
Advantage of Reentrant Monitor
It
eliminates the possibility of single thread deadlocking
Let's
understand the java reentrant monitor by the example given below:
1.
class Reentrant {
2.
public synchronized void m() {
3.
n();
4.
System.out.println("this is m() method");
5.
}
6.
public synchronized void n() {
7.
System.out.println("this is n() method");
8.
}
9.
}
In
this class, m and n are the synchronized methods. The m() method internally
calls the n() method.
Now
let's call the m() method on a thread. In the class given below, we are
creating thread using annonymous class.
1.
public class ReentrantExample{
2.
public static void main(String args[]){
3.
final ReentrantExample re=new ReentrantExample();
4.
5.
Thread t1=new Thread(){
6.
public void run(){
7.
re.m();//calling method of Reentrant class
8.
}
9.
};
10. t1.start();
11. }}
Output: this is n() method
this is m() method
public class ProducerConsumerTest {
public static void main(String[] args) {
CubbyHole c = new CubbyHole();
Producer p1 = new Producer(c, 1);
Consumer c1 = new Consumer(c, 1);
p1.start();
c1.start();
}
}
class CubbyHole {
private int contents;
private boolean available = false;
public synchronized int get() {
while (available == false) {
try {
wait();
} catch (InterruptedException e) {
}
}
available = false;
notifyAll();
return contents;
}
public synchronized void put(int value) {
while (available == true) {
try {
wait();
} catch (InterruptedException e) {
}
}
contents = value;
available = true;
notifyAll();
}
}
class Consumer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Consumer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
value = cubbyhole.get();
System.out.println("Consumer
#" + this.number
+ " got:
" + value);
}
}
}
class Producer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Producer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
for (int i = 0; i < 10; i++) {
cubbyhole.put(i);
System.out.println("Producer
#" + this.number
+ " put:
" + i);
try {
sleep((int)(Math.random() *
100));
} catch (InterruptedException e) {
}
}
}
}
D:\Threads>java
ProducerConsumerTest
Producer #1 put: 0
Consumer #1 got: 0
Producer #1 put: 1
Consumer #1 got: 1
Producer #1 put: 2
Consumer #1 got: 2
Consumer #1 got: 3
Producer #1 put: 3
Producer #1 put: 4
Consumer #1 got: 4
Producer #1 put: 5
Consumer #1 got: 5
Producer #1 put: 6
Consumer #1 got: 6
Producer #1 put: 7
Consumer #1 got: 7
Producer #1 put: 8
Consumer #1 got: 8
Producer #1 put: 9
Consumer #1 got: 9
class MyThread extends Thread {
boolean stopped;
MyThread(ThreadGroup tg, String name) {
super(tg, name);
stopped = false;
}
public void run() {
System.out.println(Thread.currentThread().getName() + "
starting.");
try {
for (int i = 1; i < 1000; i++) {
System.out.print(".");
Thread.sleep(250);
synchronized (this) {
if (stopped)
break;
}
}
} catch (Exception exc) {
System.out.println(Thread.currentThread().getName() + "
interrupted.");
}
System.out.println(Thread.currentThread().getName() + "
exiting.");
}
synchronized void myStop() {
stopped = true;
}
}
public class Main {
public static void main(String args[]) throws Exception {
ThreadGroup tg = new ThreadGroup("My Group");
MyThread thrd = new MyThread(tg, "MyThread #1");
MyThread thrd2 = new MyThread(tg, "MyThread #2");
MyThread thrd3 = new MyThread(tg, "MyThread #3");
thrd.start();
thrd2.start();
thrd3.start();
Thread.sleep(1000);
System.out.println(tg.activeCount() + " threads in thread
group.");
Thread thrds[] = new Thread[tg.activeCount()];
tg.enumerate(thrds);
for (Thread t : thrds)
System.out.println(t.getName());
thrd.myStop();
Thread.sleep(1000);
System.out.println(tg.activeCount() + " threads in tg.");
tg.interrupt();
}
}
D:\Threads>javac Main.java
D:\Threads>java Main
MyThread #1 starting.
.MyThread #2 starting.
.MyThread #3 starting.
..........3 threads in thread group.
MyThread #1
MyThread #2
MyThread #3
....MyThread #1 exiting.
.....2 threads in tg.
MyThread #3 interrupted.
MyThread #3 exiting.
MyThread #2 interrupted.
MyThread #2 exiting.
import
java.util.concurrent.ThreadLocalRandom;
public class Test {
public static void main(String[] args) {
System.out.println("Five random integers");
for (int i = 0; i < 5; i++) {
System.out.println(ThreadLocalRandom.current().nextInt());
}
System.out.println("Random double number between 0.0 and
35.0");
System.out.println(ThreadLocalRandom.current().nextDouble(35.0));
System.out.println("Five random Long numbers between 1234567 and
7654321");
for (int i = 0; i < 5; i++) {
System.out.println(ThreadLocalRandom.current().nextLong(1234567L,
7654321L));
}
}
}
D:\Threads>javac Test.java
D:\Threads>java Test
Five random integers
-1015090715
1836845809
1727764424
1201467739
249156533
Random double number between 0.0 and
35.0
31.02403012421116
Five random Long numbers between
1234567 and 7654321
4562447
1575288
2662380
2870287
2144865
కామెంట్లు లేవు:
కామెంట్ను పోస్ట్ చేయండి