Showing posts with label Java Thread. Show all posts
Showing posts with label Java Thread. Show all posts

Monday, July 1, 2024

Unit Testing of ExecutorService in Java With No Thread sleep

Unit Testing of ExecutorService in Java With No Thread sleep

Unit testing concurrent code, especially code utilizing ExecutorService, presents unique challenges due to its asynchronous nature. Traditional approaches often involve using Thread.sleep() to wait for tasks to be completed, but this method is unreliable and can lead to flaky tests. In this article, we’ll explore alternative strategies to unit test ExecutorService without relying on Thread sleep method. This ensures reliable tests that do not depend on arbitrary sleep durations.

1. Understanding ExecutorService


ExecutorService is a framework in Java for executing tasks asynchronously. It manages a pool of threads and allows you to submit tasks for concurrent execution. Testing code that uses ExecutorService typically involves verifying that tasks are executed correctly and that the service behaves as expected under various conditions.

1.1 Challenges with Thread.sleep()

Using Thread.sleep() in tests introduces several issues:

  • Non-deterministic Tests: Timing-based tests can be unpredictable and may fail randomly due to variations in thread scheduling and execution speed.
  • Slow Tests: Sleeping for a fixed duration can make tests unnecessarily slow, especially if tasks complete quickly or if longer delays are required to ensure completion.

2. Alternative Approaches to Unit Testing ExecutorService


To write reliable tests for ExecutorService without Thread.sleep(), consider the following approaches. First, we create a MyRunnable class that implements the Runnable interface and performs a long-running calculation (In this article, we are calculating the sum of a large range of numbers).

MyRunnable.java

public class MyRunnable implements Runnable {
 
    private final long start;
    private final long end;
    private long result;
 
    public MyRunnable(long start, long end) {
        this.start = start;
        this.end = end;
    }
 
    @Override
    public void run() {
        result = 0;
        for (long i = start; i <= end; i++) {
            result += i;
        }
        System.out.println("Calculation complete. Result: " + result);
    }
 
    public long getResult() {
        return result;
    }
}

2.1 Use Future to Get the Result

To get the result of the task and ensure completion, we can use Future.

FutureExampleTest.java

public class FutureExampleTest {
     
    @Test
    public void testFutureWithLongRunningCalculation() throws Exception {
         
        ExecutorService executor = Executors.newSingleThreadExecutor();
 
        // Create an instance of MyRunnable with a long-running calculation
        MyRunnable task = new MyRunnable(1, 1000000000L);
 
        // Submit the task to the executor and get a Future
        Future<?> future = executor.submit(task);
 
        // Wait for the task to complete and get the result
        future.get(); // Blocks until the task completes
 
        // Verify the result
        long expected = (1000000000L * (1000000000L + 1)) / 2;
        assertEquals(expected, task.getResult());
 
        // Shutdown the executor
        executor.shutdown();
    }
     
}

In this example, we submit the MyRunnable task to the executor and get a Future object. The future.get() method blocks until the task is completed, ensuring we can retrieve the result after completion.

2.2 Use CountDownLatch for Synchronization

To ensure the parent thread waits for the task to complete without using Thread.sleep(), we can use CountDownLatch.

ExecutorServiceExampleTest.java

public class ExecutorServiceExampleTest {
     
    @Test
    public void testExecutorServiceWithLongRunningCalculation() throws InterruptedException {
         
        ExecutorService executor = Executors.newSingleThreadExecutor();
        CountDownLatch latch = new CountDownLatch(1);
 
        // Create a runnable with a long-running calculation
        MyRunnable task = new MyRunnable(1, 1000000000L) {
            @Override
            public void run() {
                super.run();
                latch.countDown();
            }
        };
 
        // Submit the task to the executor
        executor.submit(task);
 
        // Wait for the task to complete
        assertTrue(latch.await(2, TimeUnit.MINUTES));
 
        // Verify the result
        long expected = (1000000000L * (1000000000L + 1)) / 2;
        assertEquals(expected, task.getResult());
 
        // Shutdown the executor
        executor.shutdown();
    }
     
}

This approach uses a CountDownLatch to synchronize the completion of the task. First, we create a CountDownLatch with a count of 1 and define an anonymous subclass of MyRunnable that counts down the latch when the task completes.

Next, we submit this task to the executor and use latch.await() to wait for the task to complete, verifying with assertTrue that the task finishes within the specified timeout. After the task is completed, we verify the result using assertEquals. Finally, we shut down the executor.

2.3 Use Shutdown and Await Termination

To ensure the executor shuts down gracefully after the tasks complete, use shutdown and awaitTermination.

ShutDownExampleTest.java

public class ShutDownExampleTest {
     
    @Test
    public void testShutdownWithLongRunningCalculation() throws InterruptedException {
         
        ExecutorService executor = Executors.newSingleThreadExecutor();
 
        // Create an instance of MyRunnable with a long-running calculation
        MyRunnable task = new MyRunnable(1, 1000000000L);
 
        // Submit the task to the executor
        executor.submit(task);
 
        // Shutdown the executor
        executor.shutdown();
 
        // Wait for existing tasks to complete
        assertTrue(executor.awaitTermination(2, TimeUnit.MINUTES));
 
        // Verify the result
        long expected = (1000000000L * (1000000000L + 1)) / 2;
        assertEquals(expected, task.getResult());
    }    
}

In this approach, we ensure the executor shuts down gracefully by calling shutdown() and then awaitTermination() to wait for existing tasks to complete. If tasks do not complete within the specified timeout, we call shutdownNow() to cancel currently executing tasks and wait again.

3. Conclusion

Unit testing concurrent code with ExecutorService requires careful synchronization to ensure tests are reliable and deterministic. Avoiding Thread.sleep() is essential to prevent flaky tests and improve test execution speed. In this article, we used synchronization aids like CountDownLatch, Future, and shutdown with awaitTermination() to handle concurrency effectively in our tests. These approaches provide more reliable alternatives to Thread.sleep() for unit testing ExecutorService-based code in Java.

Source: javacodegeeks.com

Friday, December 11, 2020

ThreadLocal in Java – Example Program and Tutorial

Oracle Java ThreadLocal, Oracle Java Tutorial and Material, Core Java, Java Exam Prep

ThreadLocal in Java is another way to achieve thread-safety apart from writing immutable classes. If you have been writing multi-threaded or concurrent code in Java then you must be familiar with the cost of synchronization or locking which can greatly affect the Scalability of application, but there is no choice other than synchronizing if you are sharing objects between multiple threads.

ThreadLocal in Java is a different way to achieve thread-safety, it doesn’t address synchronization requirement, instead, it eliminates sharing by providing an explicit copy of Object to each thread. Since Object is no more shared there is no requirement of Synchronization which can improve scalability and performance of the application.

In this Java ThreadLocal tutorial, we will see important points about ThreadLocal in Java, when to use ThreadLocal in Java, and a simple example of ThreadLocal in Java program.

When to use ThreadLocal in Java

Many Java Programmers question where to use ThreadLocal in Java and some even argue the benefit of the ThreadLocal variable, but ThreadLocal

has many genuine use cases and that’s why it’s added to the standard Java Platform Library. I agree though until you are not in concurrent programming, you will rarely use ThreadLocal. Below are some well know usage of ThreadLocal class in Java:

1. ThreadLocal is fantastic to implement Per Thread Singleton classes or per thread context information like transaction id.

2. You can wrap any non Thread Safe object in ThreadLocal and suddenly its uses become Thread-safe, as it’s only being used by Thread Safe. One of the classic examples of ThreadLocal is sharing SimpleDateFormat. Since SimpleDateFormat is not thread-safe, having a global formatter may not work but having per Thread formatter will certainly work.

3. ThreadLocal provides another way to extend Thread. If you want to preserve or carry information from one method call to another you can carry it by using ThreadLocal

4. This can provide immense flexibility as you don’t need to modify any method.

On a basic level, ThreadLocal provides Thread Confinement which is an extension of the local variable. while the local variable is only accessible on the block they are declared, ThreadLocal is visible only in Single Thread. 

No two Thread can see each other’s ThreadLocal variable. A real-Life example of ThreadLocal is in J2EE application servers which uses javaThreadLocal variable to keep track of transaction and security Context.

It makes a lot of sense to share heavy objects like Database Connection as

ThreadLocal in order to avoid excessive creation and cost of locking in case of sharing global instance.

Java ThreadLocal Example – Code

import java.io.IOException;

import java.text.DateFormat;

import java.text.SimpleDateFormat;

import java.util.Date;

/**

 *

 * @author

 */

public class ThreadLocalTest {

    public static void main(String args[]) throws IOException {

        Thread t1 = new Thread(new Task());  

        Thread t2 = new Thread( new Task());

        t1.start();

        t2.start();         

    }

    /*

     * Thread safe format method because every thread will use its own DateFormat

     */

    public static String threadSafeFormat(Date date){

        DateFormat formatter = PerThreadFormatter.getDateFormatter();

        return formatter.format(date);

    }

}

/*

 * Thread Safe implementation of SimpleDateFormat

 * Each Thread will get its own instance of SimpleDateFormat which will not be shared between other threads. *

 */

class PerThreadFormatter {

    private static final ThreadLocal<simpledateformat> dateFormatHolder = new ThreadLocal<simpledateformat>() {

        /*

         * initialValue() is called

         */

        @Override

        protected SimpleDateFormat initialValue() {

            System.out.println("Creating SimpleDateFormat for Thread : " + Thread.currentThread().getName());

            return new SimpleDateFormat("dd/MM/yyyy");

        }

    };

    /*

     * Every time there is a call for DateFormat, ThreadLocal will return calling

     * Thread's copy of SimpleDateFormat

     */

    public static DateFormat getDateFormatter() {

        return dateFormatHolder.get();

    }

}

class Task implements Runnable{

    @Override

    public void run() {

        for(int i=0; i<2; i++){

            System.out.println("Thread: " + Thread.currentThread().getName() + " Formatted Date: " + ThreadLocalTest.threadSafeFormat(new Date()) );

        }      

    }

}

Output:

Creating SimpleDateFormat for Thread: Thread-0

Creating SimpleDateFormat for Thread: Thread-1

Thread: Thread-1 Formatted Date: 30/05/2012

Thread: Thread-1 Formatted Date: 30/05/2012

Thread: Thread-0 Formatted Date: 30/05/2012

Thread: Thread-0 Formatted Date: 30/05/2012

</simpledateformat></simpledateformat>

Output

Creating SimpleDateFormat for Thread: Thread-0

Creating SimpleDateFormat for Thread: Thread-1

Thread: Thread-1 Formatted Date: 30/05/2012

Thread: Thread-1 Formatted Date: 30/05/2012

Thread: Thread-0 Formatted Date: 30/05/2012

Thread: Thread-0 Formatted Date: 30/05/2012

Oracle Java ThreadLocal, Oracle Java Tutorial and Material, Core Java, Java Exam Prep
If you look at the output of the above program then you will find that when a different thread calls getFormatter() method of ThreadLocal class than its call its initialValue() method which creates an exclusive instance of

SimpleDateFormat for that Thread. 

Since SimpleDateFormat is not shared between thread and essentially local to the thread which creates its own threadSafFormat() method is completely thread-safe.

Important points on Java ThreadLocal Class

1. ThreadLocal in Java is introduced on JDK 1.2 but it later generified in JDK 1.4 to introduce type safety on ThreadLocal variable.

2. ThreadLocal can be associated with Thread scope, all the code which is executed by Thread has access to ThreadLocal variables but two thread can not see each other's ThreadLocal variable.

3. Each thread holds an exclusive copy of the ThreadLocal variable which becomes eligible to Garbage collection after thread finished or died, normally or due to any Exception, Given those ThreadLocal variable doesn't have any other live references.

4. ThreadLocal variables in Java are generally private static fields in Classes and maintain its state inside Thread.

We saw how ThreadLocal in Java opens another avenue for thread-safety. Though the concept of thread-safety by confining object to Thread is there from JDK 1.0 and many programmers have their own custom ThreadLocal

classes, having ThreadLocal in Java API makes it a lot more easy and standard. Think about the ThreadLocal variable while designing concurrency in your application. 

Don't misunderstand that ThreadLocal is an alternative to Synchronization, it all depends upon the design. If the design allows each thread to have their own copy of the object then ThreadLocal is there to use.

Source: javacodegeeks.com

Friday, October 16, 2020

Lifecycle and States of a Thread in Java

A thread in Java at any point of time exists in any one of the following states. A thread lies only in one of the shown states at any instant:

1. New

2. Runnable

3. Blocked

4. Waiting

5. Timed Waiting

6. Terminated

The diagram shown below represent various states of a thread at any instant of time.

Oracle Java Exam Prep, Oracle Java Learning, Oracle Java Tutorial and Material, Oracle Java Guides

Life Cycle of a thread


1. New Thread: When a new thread is created, it is in the new state. The thread has not yet started to run when thread is in this state. When a thread lies in the new state, it’s code is yet to be run and hasn’t started to execute.

2. Runnable State: A thread that is ready to run is moved to runnable state. In this state, a thread might actually be running or it might be ready run at any instant of time. It is the responsibility of the thread scheduler to give the thread, time to run.
A multi-threaded program allocates a fixed amount of time to each individual thread. Each and every thread runs for a short while and then pauses and relinquishes the CPU to another thread, so that other threads can get a chance to run. When this happens, all such threads that are ready to run, waiting for the CPU and the currently running thread lies in runnable state.

3. Blocked/Waiting state: When a thread is temporarily inactive, then it’s in one of the following states:

◉ Blocked
◉ Waiting

For example, when a thread is waiting for I/O to complete, it lies in the blocked state. It’s the responsibility of the thread scheduler to reactivate and schedule a blocked/waiting thread. A thread in this state cannot continue its execution any further until it is moved to runnable state. Any thread in these states does not consume any CPU cycle.

A thread is in the blocked state when it tries to access a protected section of code that is currently locked by some other thread. When the protected section is unlocked, the schedule picks one of the thread which is blocked for that section and moves it to the runnable state. Whereas, a thread is in the waiting state when it waits for another thread on a condition. When this condition is fulfilled, the scheduler is notified and the waiting thread is moved to runnable state.

If a currently running thread is moved to blocked/waiting state, another thread in the runnable state is scheduled by the thread scheduler to run. It is the responsibility of thread scheduler to determine which thread to run.

4. Timed Waiting: A thread lies in timed waiting state when it calls a method with a time out parameter. A thread lies in this state until the timeout is completed or until a notification is received. For example, when a thread calls sleep or a conditional wait, it is moved to a timed waiting state.

5. Terminated State: A thread terminates because of either of the following reasons:

◉ Because it exists normally. This happens when the code of thread has entirely executed by the program.
◉ Because there occurred some unusual erroneous event, like segmentation fault or an unhandled exception.

A thread that lies in a terminated state does no longer consumes any cycles of CPU.

Implementing Thread States in Java


In Java, to get the current state of the thread, use Thread.getState() method to get the current state of the thread. Java provides java.lang.Thread.State class that defines the ENUM constants for the state of a thread, as summary of which is given below:

1. Constant type: New

Declaration: public static final Thread.State NEW

Description: Thread state for a thread which has not yet started.

2. Constant type: Runnable

Declaration: public static final Thread.State RUNNABLE

Description: Thread state for a runnable thread. A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.

3. Constant type: Blocked

Declaration: public static final Thread.State BLOCKED

Description: Thread state for a thread blocked waiting for a monitor lock. A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling Object.wait().

4. Constant type: Waiting

Declaration: public static final Thread.State WAITING

Description: Thread state for a waiting thread. Thread state for a waiting thread. A thread is in the waiting state due to calling one of the following methods:

◉ Object.wait with no timeout
◉ Thread.join with no timeout
◉ LockSupport.park

A thread in the waiting state is waiting for another thread to perform a particular action.

5. Constant type: Timed Waiting

Declaration: public static final Thread.State TIMED_WAITING

Description: Thread state for a waiting thread with a specified waiting time. A thread is in the timed waiting state due to calling one of the following methods with a specified positive waiting time:

◉ Thread.sleep
◉ Object.wait with timeout
◉ Thread.join with timeout
◉ LockSupport.parkNanos
◉ LockSupport.parkUntil

6. Constant type: Terminated

Declaration: public static final Thread.State TERMINATED

Description: Thread state for a terminated thread. The thread has completed execution.

// Java program to demonstrate thread states 
class thread implements Runnable 
public void run() 
// moving thread2 to timed waiting state 
try
Thread.sleep(1500); 
catch (InterruptedException e) 
e.printStackTrace(); 
System.out.println("State of thread1 while it called join() method on thread2 -"+ 
Test.thread1.getState()); 
try
Thread.sleep(200); 
catch (InterruptedException e) 
e.printStackTrace(); 
}  

public class Test implements Runnable 
public static Thread thread1; 
public static Test obj; 
public static void main(String[] args) 
obj = new Test(); 
thread1 = new Thread(obj); 
// thread1 created and is currently in the NEW state. 
System.out.println("State of thread1 after creating it - " + thread1.getState()); 
thread1.start(); 
// thread1 moved to Runnable state 
System.out.println("State of thread1 after calling .start() method on it - " + 
thread1.getState()); 
public void run() 
thread myThread = new thread(); 
Thread thread2 = new Thread(myThread); 
// thread1 created and is currently in the NEW state. 
System.out.println("State of thread2 after creating it - "+ thread2.getState()); 
thread2.start(); 
// thread2 moved to Runnable state 
System.out.println("State of thread2 after calling .start() method on it - " + 
thread2.getState()); 
// moving thread1 to timed waiting state 
try
//moving thread1 to timed waiting state 
Thread.sleep(200); 
catch (InterruptedException e) 
e.printStackTrace(); 
System.out.println("State of thread2 after calling .sleep() method on it - "+ 
thread2.getState() ); 
try
// waiting for thread2 to die 
thread2.join(); 
catch (InterruptedException e) 
e.printStackTrace(); 
System.out.println("State of thread2 when it has finished it's execution - " + 
thread2.getState()); 

Oracle Java Exam Prep, Oracle Java Learning, Oracle Java Tutorial and Material, Oracle Java Guides

Output:

State of thread1 after creating it - NEW
State of thread1 after calling .start() method on it - RUNNABLE
State of thread2 after creating it - NEW
State of thread2 after calling .start() method on it - RUNNABLE
State of thread2 after calling .sleep() method on it - TIMED_WAITING
State of thread1 while it called join() method on thread2 -WAITING
State of thread2 when it has finished it's execution - TERMINATED

Explanation: When a new thread is created, the thread is in the NEW state. When .start() method is called on a thread, the thread scheduler moves it to Runnable state. Whenever join() method is called on a thread instance, the current thread executing that statement will wait for this thread to move to Terminated state. So, before the final statement is printed on the console, the program calls join() on thread2 making the thread1 wait while thread2 completes its execution and is moved to Terminated state. thread1 goes to Waiting state because it is waiting for thread2 to complete it’s execution as it has called join on thread2.

Monday, August 10, 2020

How to create a thread without implementing the Runnable interface in Java?

Oracle Java Certification, Oracle Java Exam Prep, Oracle Java Prep, Oracle Java Study Materials

A quick programming guide to creating a thread without using the Runnable interface in java. This can be achieved using new Thread ( new Runnable() { public void run(){}});.

1. Introduction


In this tutorial, You’ll learn how to create a thread without implementing the Runnable interface in Java.

Thread is a lightweight process and every program in java starts in a thread. So by default when you run the main program that has the main() method, JVM will create a thread to run the main program. The default thread is called “main thread“.

Additionally, Java supports multithreading which means you can one or more threads at the same time.

Let us see the different ways to create a thread in java using Anonymous implementation for the Runnable interface.

2. Anonymous Runnable Implementation to Create A Thread


Instead of creating a separate class and implements the Runnable interface directly, you can create as below using Anonymous implementation concept.

package com.javaprogramto.threads;

public class AnonymousRunnableThread {

    public static void main(String[] args) {

        new Thread(new Runnable() {
            @Override            public void run() {

                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName()+", i value from thread- "+i);
                }
            }
        }).start();

        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+", i value from main thread - "+i);
        }
    }
}

Output:

main, i value from main thread – 0

Thread-0, i value from thread- 0

main, i value from main thread – 1

Thread-0, i value from thread- 1

main, i value from main thread – 2

Thread-0, i value from thread- 2

main, i value from main thread – 3

Thread-0, i value from thread- 3

main, i value from main thread – 4

Thread-0, i value from thread- 4

main, i value from main thread – 5

Thread-0, i value from thread- 5

main, i value from main thread – 6

Thread-0, i value from thread- 6

main, i value from main thread – 7

Thread-0, i value from thread- 7

main, i value from main thread – 8

Thread-0, i value from thread- 8

main, i value from main thread – 9

Thread-0, i value from thread- 9

3. Anonymous Runnable Implementation to print even numbers


Oracle Java Certification, Oracle Java Exam Prep, Oracle Java Prep, Oracle Java Study Materials
package com.javaprogramto.threads;

public class AnonymousRunnableThreadPrintEvenNumbers {

    public static void main(String[] args) {

        new Thread(new Runnable() {
            @Override            public void run() {

                for (int i = 0; i <= 10; i++) {
                     if(i % 2 == 0){
                         System.out.println(Thread.currentThread().getName() +" - "+i);
                     }
                }

                System.out.println("Child thread ended "+Thread.currentThread().getName());
            }
        }).start();

        System.out.println("main thread ended.");
    }
}

Output:

main thread ended.

Thread-0 – 0

Thread-0 – 2

Thread-0 – 4

Thread-0 – 6

Thread-0 – 8

Thread-0 – 10

Child thread ended Thread-0

Wednesday, March 4, 2020

Thread, code and data - Story of a Multithreading Program in Java

Oracle Java Thread, Oracle Java Multithreading, Oracle Core Java, Oracle Java Prep

There are certain things, which you don't learn on academics or training class, you develop those understanding after few years of work experience, and then you realize, it was very basic, how come I had missed that all those years. Understanding of how a multi-threaded Java program executes is one of such things. You definitely have heard about threads, how to start a thread, how to stop a thread, definitions like its independent path of execution, all funky libraries to deal with inter-thread communication, yet when it comes to debugging a multithreaded Java program, you struggle.

At least I can say this from my personal experience. Debugging is in my opinion real trainer, you will learn a subtle concept and develop an understanding which will last long, only through debugging.

In this article, I am going to talk about three important things about any program execution, not just Java, Thread, code, and data.

Once you have a good understanding of how these three work together, it would be much easier for you to understand how a program is executing, why a certain bug comes only sometimes, why a particular bug comes all time and why a particular bug is truly random.

How Thread, Code, and Data work together


What is a program? In short, it's a piece of code, which is translated into binary instruction for  CPU. CPU is the one, who executes those instructions e.g. fetch data from memory, add data, subtract data etc. In short, what you write is your program, the Code.

What varies between the different execution of the same program, is data. It's not just mean restarting the program, but a cycle of processing, for example, for an electronic trading application, processing one order is one execution. You can process thousands of order in one minute and with each iteration, data varies.

One more thing to note is that you can create Threads in code, which will then run parallel and execute code, which is written inside their run() method. The key thing to remember is threads can run parallel.

When a Java program starts, one thread known as main thread is created, which executed code written inside the main method, if you create a thread, then those threads are created and started by the main thread, once started they start executing code written in their run() method.

Oracle Java Thread, Oracle Java Multithreading, Oracle Core Java, Oracle Java Prep

So if you have 10 threads for processing Orders, they will run in parallel. In short, Thread executes code, with data coming in. Now, we will see three different kinds of issue, we talked about

1) Issues, which always comes

2) Issues, which comes only sometimes, but consistent with the same input

3) Issues, which is truly random

Issue one is most likely due to faulty code, also known as programming errors e.g. accessing the invalid index of an array, accessing Object's method after making it null or even before initializing it. They are easy to fix, as you know their place.

 You just need to have knowledge of programming language and API to fix this error.

The second issue is more likely to do with data than code. Only sometimes, but always come with the same input, could be because of incorrect boundary handling, malformed data like Order without certain fields for example price, quantity etc.

Your program should always be written robustly so that it won't crash if incorrect data is given as input. The impact should only be with that order, the rest of the order must execute properly.

The third issue is more likely coming because of multithreading, where order and interleaving of multiple thread execution causing race conditions or deadlocks. They are random because they only appear if certain random things happen e.g. thread 2 getting CPU before thread 1, getting a lock on incorrect order.

Remember, Thread scheduler and Operating system are responsible for allocating CPU to threads, they can pause them, take CPU from them at any time, all these can create a unique scenario, which exposes multithreading and synchronization issue.

Your code never depends upon the order of thread etc, it must be robust to run perfectly in all condition.

In short, remember thread executes code with data given as input. Each thread work with the same code but different data. While debugging issue, pay attention to all three, Thread, Code and data.

Saturday, February 29, 2020

What is difference between wait and sleep in Java Thread?

Oracle Java Thread, Oracle Java Tutorial and Material, Oracle Java Certification, Oracle Java Prep, Core Java


Wait vs sleep in Java


Differences between wait and sleep method in Java multi-threading is one of the very old questions asked in Java interviews. Though both wait and sleep put thread on waiting state, they are completely different in terms of behavior and use cases. Thread.sleep(long millis) is meant for introducing pause, releasing CPU and giving another thread an opportunity to execute while wait is used for inter thread communication in Java. These methods are defined in java.lang.Object class and available to every object in Java. It is based upon object lock, if you remember every object in Java has implicit lock, also known as monitor. When a thread enter into a synchronized method it acquired the lock which is used to protect the critical reason e.g. it acquired lock on current object if it is going inside an instance synchronized method and lock object on class literal if its entering into a static synchronized method. By using wait() and notify() method two threads can communicate with each other which is key to solve many concurrency problems e.g. produce consumer problem, dining philosopher problem, reader and writer problem, and to implement several Concurrency designs.

In this tutorial, you will learn about following this about wait() and sleep() method in Java :

What is wait() method in Java?
What is sleep() method in Java?
What is difference between wait and sleep in Java?
Where to use wait and sleep in Java?

What is wait and sleep method in Java


Wait method is defined in Object class and it available to all object, wait() method is always discussed along with its counterpart notify() and notifyAll() method and used in inter thread communication in Java.

The wait() method puts a thread on wait by checking some condition like in Producer Consumer problem, producer thread should wait if Queue is full or Consumer thread should wait if Queue is empty.

The notify() method is used to wake up waiting thread by communicating that waiting condition is over now for example once producer thread puts an item on empty queue it can notify Consumer thread that Queue is not empty any more. On the other hand Sleep() method is used to introduce pause on Java application.

You can put a Thread on sleep, where it does not do anything and relinquish the CPU for specified duration. When a Thread goes to Sleep it can be either wake up normally after sleep duration elapsed or it can be woken up abnormally by interrupting it.

Difference between Wait and Sleep method in Java Thread


In last section we saw what is wait and sleep method and in this section we will see what are differences between wait and sleep method in Java. As I told before apart from waiting they are completely different to each other:

Oracle Java Thread, Oracle Java Tutorial and Material, Oracle Java Certification, Oracle Java Prep, Core Java
1) First and most important difference between Wait and sleep method is that wait method must be called from synchronized context i.e. from synchronized method or block in Java. If you call wait method without synchronization, it will throw IllegalMonitorStateException in Java. On the other hand there is no requirement of synchronization for calling sleep method , you can call it normally.

2) Second worth noting difference between wait and sleep method is that, wait operates on Object and defined in Object class while sleep operates on current Thread and defined in java.lang.Thread class.

3) Third and another significant difference between wait and sleep in Java is that, wait() method releases the lock of object on which it has called, it does release other locks if it holds any while sleep method of Thread class does not release any lock at all.

4) wait method needs to be called from a loop in order to deal with false alarm i.e. waking even though waiting condition still holds true, while there is no such thing for sleep method in Java. its better not to call Sleep method from loop.

here is code snippet for calling wait and sleep method in Java

synchronized(monitor)
while(condition == true){ monitor.wait())  //releases monitor lock

Thread.sleep(100); //puts current thread on Sleep

5) One more difference between wait and sleep method which is not as significant as previous ones is that wait() is a non static method while sleep() is static method in Java.

Oracle Java Thread, Oracle Java Tutorial and Material, Oracle Java Certification, Oracle Java Prep, Core Java

Where to use wait and sleep method in Java


By reading properties and behavior of wait and sleep method it's clear that wait() method should be used in conjunction with notify() or notifyAll() method and intended for communication between two threads in Java while Thread.sleep() method is a utility method to introduce short pauses during program or thread execution. Given the requirement of synchronization for wait, it should not be used just to introduce pause or sleep in Java.

In summary wait and sleep method are completely different to each other and have different use cases. Use wait() and notify() method for inter thread communication while use sleep() method for introducing small pause during thread execution. Also remember, that wait() method will release the lock acquired when it entered into synchronized block or method, but sleep() method will keep the lock with itself. So if you design require releasing the lock during wait period then use wait() and notify method otherwise just use sleep().