Why should I use notify? - java

I'm reading through my SCJP book and I'm on the chapter about threads, and I am wondering why you should use notify at all.
Here is my sample program using notify:
class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
public void run() {
synchronized(this) {
for(int i = 0; i < 100000000; i++){
total++;
}
notify();
}
for(int i = 0; i < 100000000; i++){
total++;
}
}
}
If I take out the notify call, it still executes in the same way. I.E., once the lock is released, the b.wait() stops blocking eventually and we get a semi random number between 100000000 and 200000000, depending on the scheduler.
This code:
class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
public void run() {
synchronized(this) {
for(int i = 0; i < 100000000; i++){
total++;
}
notify();
}
}
}
Always results in 100000000 getting printed regardless wither the notify is there or not.
And this code:
class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
public void run() {
synchronized(this) {
for(int i = 0; i < 100000000; i++){
total++;
}
notify();
for(int i = 0; i < 100000000; i++){
total++;
}
}
}
}
Always prints out 200000000 regardless of the notify being present or absent.
So as far as I can tell, the only thing the notify does is possibly waking up a thread earlier than needed, if that is the case, why use notify at all? Why not wait for the lock to be released and let the JVM restart the other thread?

Unless you or someone else calls notify(), the wait() should continue forever, barring spurious wakes. Are you sure nothing's interrupting the thread?
Basically you use notify() precisely to wake up threads. If you don't need to put a thread to sleep until another thread can notify it that it should wake up, don't use it.
EDIT: Okay, I've reproduced this behaviour - and I suspect it's because you're calling wait() on the thread object itself. My guess is that the Thread object gets notified when the thread terminates.
Try waiting on a shared plain Object, like this:
class ThreadA {
static Object monitor = new Object();
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
synchronized(monitor) {
try {
System.out.println("Waiting for b to complete...");
monitor.wait();
}catch(InterruptedException e) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
public void run() {
synchronized(ThreadA.monitor) {
for (int i = 0; i < 100000000; i++) {
total++;
}
// ThreadA.monitor.notify();
}
}
}
If you uncomment that line, the program terminates - otherwise it doesn't.
EDIT: I've actually found some documentation on this. From Thread.join(millis, nanos):
As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.

Related

correct approach for 2 threads alternatively printing numbers

I have written a program which creates a 2 new thread and shares a common lock object to print numbers alternatively.
Wanted to know if the approach for using wait() and notify() is correct?
Main Class
public class MyMain {
public static void main(String[] args) {
MyThread1 obj = new MyThread1();
Thread thread1 = new Thread(obj);
Thread thread2 = new Thread(obj);
thread1.setName("t1");
thread2.setName("t2");
thread1.start();
thread2.start();
}
}
Thread Class
public class MyThread1 implements Runnable{
int i = 0;
#Override
public synchronized void run() {
while(i<10)
{
if(i%2==0)
{
try{
notify();
System.out.println(Thread.currentThread().getName()+" prints "+i);
i++;
wait();
}catch(Exception e){ e.printStackTrace(); }
}else
{
try{
notify();
System.out.println(Thread.currentThread().getName()+" prints "+i);
i++;
wait();
}catch(Exception e){ e.printStackTrace(); }
}
}
}
}
Can there be a better usage of wait() and notify() instead of using it in both the if conditions?
Since there you have some code repetition I'd just go with something like:
while(true) {
//If it's not my turn I'll wait.
if(i%2==0) wait();
// If I've reached this point is because:
// 1 it was my turn OR 2 someone waked me up (because it's my turn)
System.out.println(Thread.currentThread()": "+i);
i++; // Now is the other thread's turn
// So we wake him up
notify();
}
Also, be very careful with monitor's behaviour. (Thread waiting/notifying queues).

"notifyAll()" in java threads: unexpected waiting time

I am reading some code in OCA/OCP Java SE 7 Programmer I & II Study Guide, and I got stuck on an example:
package threads;
class Totalizer implements Runnable
{
int total = 0;
public void run(){
synchronized(this){
for(int i = 0; i < 100; i++){
total += i;
}
notifyAll();
}
}
}
class Tester extends Thread
{
Totalizer t;
public Tester(Totalizer tot){t = tot;}
public void run(){
synchronized(t){
try {
System.out.println("Waiting for calculation...");
t.wait();
} catch (InterruptedException e) {}
System.out.println(t.total);
}
}
public static void main(String[] args){
Totalizer t = new Totalizer();
new Tester(t).start();
new Tester(t).start();
new Tester(t).start();
}
}
//
When I run main(), it prints:
waiting for calculation...
waiting for calculation...
waiting for calculation...
and nothing happens, no calculation, nothing. I can't figure out what is wrong with this code.
Two points.
The most obvious one is that you never start the Totalizer runnable, so the notifyAll call is never issued. You need to have a line
new Thread(t).start();
somewhere in your main method. But even if you do that, it won't work reliably, as the wait call may be invoked after the notifyAll call. It may also print the output too early, as the wait call can wake up without a notifyAll as well.
The Javadoc for Object.wait() describes what you need to do:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
So, you can't just call Object.wait just like that, if you want to use it correctly. This is because:
You don't know if the condition was already satisfied earlier, before you started waiting
The wait call may also wake up without a notify call
In your case, you need a condition variable that you can check. For example, you can change your code like this:
class Totalizer implements Runnable
{
int total = 0;
boolean calculationComplete; // Condition to check in wait()
public void run() {
for(int i = 0; i < 100; i++) {
total += i;
}
synchronized (this) {
// Indicate condition for wait() is now true
calculationComplete = true;
notifyAll();
}
}
}
class Tester extends Thread
{
Totalizer t;
public Tester(Totalizer tot){t = tot;}
public void run(){
synchronized(t) {
System.out.println("Waiting for calculation...");
// Loop, terminate when condition is true
while (!t.calculationComplete) {
try {
t.wait();
} catch (InterruptedException e) {}
}
System.out.println(t.total);
}
}

Java Threads: How to print alphabets and numbers using two threads one at a time

I am trying to work around with threads in java. Though I understand that threads output are unpredictable, However was wondering if there is a way to do that.
I have to implement two threads, one prints alphabets(a,b,c...z) and other prints numbers(1,2,3....26). Have to implement it in such a way that the output should be a,1,b,2,c,3,d,4......z,26. Below is my code but it doesn't give the desired output.
public class ThreadsExample {
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t.start();
t2.start();
}
}
class Runnable2 implements Runnable{
public void run(){
for(char i='a';i<='z';i++) {
System.out.print(i+",");
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=1;i<=26;i++) {
System.out.print(i+",");
}
}
}
What tweak should I make in the code to get the desired output? How does synchronization helps here? Or is it really possible when working with Threads at all?
PS: This is not an assignment or some exercise. Its self learning.
It is possible. You need to synchronize it well.
Approach Pseudocode
query some (synchronized) state
state will tell whether nums or chars are allowed
if state allows char and caller will put chars, do it now and change state and wake up waiting threads
if not, wait
if state allows numbers and caller will put numbers, do it now and change state and wake up waiting threads
if not, wait
Java code
public class ThreadsExample {
public static ThreadsExample output = new ThreadsExample ();
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t.start();
t2.start();
}
private Object syncher = new Object (); // we use an explicit synch Object, you could use annotation on methods, too. like ABHISHEK did.
// explicit allows to deal with more complex situations, especially you could have more the one locking Object
private int state = 0; // 0 allows chars, 1 allows ints
public void print (char pChar) {
synchronized (syncher) { // prevent the other print to access state
while (true) {
if (state == 0) { // char are allowed
System.out.print(pChar + ","); // print it
state = 1; // now allow ints
syncher.notify(); // wake up all waiting threads
return;
} else { // not allowed for now
try {
syncher.wait(); // wait on wake up
} catch (InterruptedException e) {
}
}
}
}
}
public void print (int pInt) {
synchronized (syncher) {
while (true) {
if (state == 1) {
System.out.print(pInt + ",");
state = 0;
syncher.notify();
return;
} else {
try {
syncher.wait();
} catch (InterruptedException e) {
}
}
}
}
}
}
class Runnable2 implements Runnable{
public void run(){
for(char i='a';i<='z';i++) {
ThreadsExample.output.print(i);
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=1;i<=26;i++) {
ThreadsExample.output.print(i);
}
}
}
Output
a,1,b,2,c,3,d,4,e,5,f,6,g,7,h,8,i,9,j,10,k,11,l,12,m,13,n,14,o,15,p,16,q,17,r,18,s,19,t,20,u,21,v,22,w,23,x,24,y,25,z,26,
The whole idea of threads: it represents a "stream of activity" that executes code independent of other threads.
In your case, you want that these two threads go in "lockstep". Thread A does one step, then Thread B, then A, then B.
In order to get there, the two threads need something "synchronize" on - in other words: A sends a signal to B when it has done its steps - and B has to wait for that signal. Then B does its thing, signals to A, ...
For starters, a simple boolean value would do. One thread sets it to true, the other to false (to indicate when it has made its step). Then the thread waits for the boolean to toggle again.
As you intend to learn things, I would just start experimenting from there. In case you want to take detours, look here for example. This might help as well.
HERE IS THE CODE::
You need to create 2 threads and implement wait and notify methods correctly you can also refer "Create two threads, one display odd & other even numbers" for your answer.
public class ThreadClass {
volatile int i = 1;
volatile Character c = 'a';
volatile boolean state = true;
synchronized public void printAlphabet() {
try {
while (!state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " +c);
state = false;
c++;
notifyAll();
}
synchronized public void printNumbers() {
try {
while (state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + i);
state = true;
i++;
notifyAll();
}
public static void main(String[] args) {
ThreadClass threadClass = new ThreadClass();
Thread t1 = new Thread() {
int k = 0;
#Override
public void run() {
while (k < 26) {
threadClass.printAlphabet();
k++;
}
}
};
t1.setName("Thread1");
Thread t2 = new Thread() {
int j = 0;
#Override
public void run() {
while (j < 26) {
threadClass.printNumbers();
j++;
}
}
};
t2.setName("Thread2");
t1.start();
t2.start();
}
}
Your threads are running at the same time. But not the way you want it, as mentioned above. You will see blocks of data from thread 1 and then a block of data from thread 2; and this is because of thread scheduling. Thread 1 is just queuing its output before thread 2.
To test this theory, increase your output to a 1000 records for example as the alphabet and 26 numbers are not as large to see this.
By doing so, you will see these 'blocks' of data. There is a way to do what you mentioned, but it is not advisable as this is not demonstrating how threads actually work but rather you forcing it to work that way.
With less Code:
class MyRunnable implements Runnable {
private static int n = 1;
private static char c = 'a';
public void run() {
for (int i = 1; i <= 26; i++) {
synchronized (this) {
try {
notifyAll();
if (Thread.currentThread().getName().equals("A")) {
System.out.print(c + ",");
c++;
} else {
System.out.print(n + ",");
n++;
}
if (i != 26) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class PrintAlphabetNumberJob {
public static void main(String[] args) throws InterruptedException {
MyRunnable r = new MyRunnable();
Thread tAlphabet = new Thread(r, "A");
Thread tNumber = new Thread(r, "N");
tAlphabet.start();
Thread.sleep(100);
tNumber.start();
}
}

how to implement wait,notify with threadexecutor in java

how to implement wait,notify with threadexecutor in java,Suppose I have two objeccts of threadExecutor and I want to perform wait,notify on that objecct can we implement that.
Here is an Example of using wait notify with ThreadExecutor in Java :
public class ExecutorServiceTest {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
ThreadB threadB = new ThreadB();
ThreadA threadA = new ThreadA(threadB);
executor.execute(threadA);
executor.execute(threadB);
executor.shutdown();
while (!executor.isTerminated());
System.out.println("Finished all threads");
}
static class ThreadA extends Thread {
private final ThreadB waitThread;
public ThreadA(ThreadB waitThread) {
this.waitThread = waitThread;
}
#Override
public void run() {
synchronized (waitThread) {
try {
waitThread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("B Count Total : " + waitThread.getCount());
for (int i = waitThread.getCount(); i < 200; i++) {
System.out.println("A Counting " + i);
}
}
}
}
static class ThreadB extends Thread {
private int count = 0;
#Override
public void run() {
synchronized (this) {
while (count < 100) {
System.out.println("B Counting " + count);
count++;
}
notify();
}
}
public int getCount() {
return count;
}
}
}
synchronized
keyword is used for exclusive accessing.
To make a method synchronized, simply add the synchronized keyword to its declaration. Then no two invocations of synchronized methods on the same object can interleave with each other.
synchronized statements must specify the object that provides the intrinsic lock:
wait()
tells the calling thread to give up the monitor and go to sleep until some other thread enters the same monitor and calls notify( ).
notify()
wakes up the first thread that called wait() on the same object.

why without calling the notify wait is releasing the lock

Please see the below code, where the notifyAll is commented. Still the main thread is printing the total? How is it possible?
public class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}}
class ThreadB extends Thread{
int total;
#Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
// notify();
}
}
}
What you see is the result of something documented in the javadoc of Thread.join():
As a thread terminates the this.notifyAll method is invoked.
Note that it goes on with
It is recommended that applications not use wait, notify, or notifyAll on Thread instances
Also note that a thread blocked on wait() can go out of its waiting state without any notification, due to spurious wakeups. And the javadoc of wait() clearly explains that wait() should always be called inside a loop.
Also note: The Java API doc for Object.wait() says, "...interrupts and spurious wakeups are possible, and this method should always be used in a loop."
That is generally true in other APIs and other languages as well. A method/function should never assume that the condition it was waiting for is true just because a wait() operation on a condition variable returned. There should always be a loop. In pseudo-code:
lock mutex
while (! ok_to_do_whatever()) {
wait on condition_variable
}
do_whatever()
unlock mutex
Try this and the waiting thread will wait forever...
public class ThreadA {
public static Object lock = new Object();
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
synchronized(lock){
try{
System.out.println("Waiting for b to complete...");
lock.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread
{
int total;
#Override
public void run(){
synchronized(ThreadA.lock){
for(int i=0; i<100 ; i++){
total += i;
}
// notify();
}
}
}

Categories