Friday, June 7, 2024

Appending a File in Node.js

In the post Writing a File in Node.js we saw how to use methods of fs module to write to a file. When you use writeFile() method it rewrites the file if file already exists. If you need to append to a file then fs module has methods to do that too.

How to append to a file in Node.js

In the fs module there are both synchronous and asynchronous methods to append to a file. Description is as given below.

  1. fs.appendFile()- This method asynchronously appends data to a file, creating the file if it does not yet exist. A callback function is provided which is called when the file append operation is completed.
  2. fs.appendFileSync- This method synchronously appends data to a file, creating the file if it does not yet exist.
  3. fsPromises.appendFile()- This method is in the fs.promises API which asynchronously appends data to a file, creating the file if it does not yet exist. Method returns a Promise object which is resolved with undefined upon success.

Using fs.appendFile()

Syntax of fs.appendFile() method is as given below.

fs.appendFile(path, data, options, callback)

The four parameters are described below-

  1. file- Path to the file where content has to be written or file descriptor (a number returned by opening the file using the open() method).
  2. data- Content to be written to the file. It can be of type string or Buffer.
  3. options- It specifies optional parameters that can be provided with write operation. Type can be either string or object. Optional parameters are described below-
    • encoding- A string value specifying the encoding of the file. Default is 'utf8'
    • mode- An integer value specifying the file mode. Default is 0o666 which means both read and write.
    • flag- Flag used in append operation. Default flag is 'a' which means open file for appending. The file is created if it does not exist.
    • flush- If true, the underlying file descriptor is flushed prior to closing it. Default value is false.
  4. callback- A function that is called when the file operation completes. Takes one argument err which denotes the error that can be thrown if append operation fails.

fs.appendFile () Example

const fs = require('fs');
var os = require("os");
const path = require('path');

const content = 'This is a line added to the file' + os.EOL;
fs.appendFile(path.join(__dirname, 'Hello.txt'), content, (err) => {
    if(err){
        console.error(err);
    }else {
        console.log("Append operation completed");
    }
})

Here os.EOL const of the 'os' module is used to add new line at the end.

Using fs.appendFileSync()

Syntax of fs.appendFileSync() method is as given below

fs.appendFileSync(path, data, options)

Description of parameters is similar to fs.appendFile()

fs.appendFileSync() Example

const fs = require('fs');
var os = require("os");
const path = require('path');

const content = 'This is a line added to the file' + os.EOL;
fs.appendFileSync(path.join(__dirname, 'Hello.txt'), content);
console.log("Append operation completed");

Using fsPromises.appendFile()

Syntax of fsPromises.appendFile() method is as given below

fsPromises.appendFile(path, data, options)

Description of parameters is similar to fs.appendFile() method as given above.

fsPromises.appendFile() example

const fs = require('fs');
const fspromises = fs.promises;
var os = require("os");
const path = require('path');

// uses async/await
const appendFile =  async (filePath) => {
    try{
        const content = 'This is a line added to the file' + os.EOL;
        await fspromises.appendFile(filePath, content);
        console.log("Append operation completed");
    } catch(error){
        console.error(err);
    }
}

// function call
appendFile(path.join(__dirname, 'Hello.txt'));

That's all for this topic Appending a File in Node.js. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Reading a File in Node.js
  2. NodeJS Event Loop
  3. NodeJS Blocking Non-blocking Code
  4. Node.js REPL
  5. NodeJS NPM Package Manager

You may also like-

  1. Matrix Addition Java Program
  2. String in Java Tutorial
  3. JavaScript Arrow Function With Examples
  4. Angular Two-Way Data Binding With Examples
  5. Passing Arguments to getBean() Method in Spring

Thursday, June 6, 2024

Java CountDownLatch With Examples

There are scenarios in an application when you want one or more threads to wait until one or more events being performed in other threads complete. CountDownLatch in Java concurrent API helps in handling such scenarios.

Note that CountDownLatch was introduced in Java 5 along with other concurrent classes like CyclicBarrier, ConcurrentHashMap, CopyOnWriteArrayList, BlockingQueue with in java.util.Concurrent package.


How CountDownLatch is used

CountDownLatch in Java, as the name suggests, can be visualized as a latch that is released only after the given number of events occur. When an instance of CountDownLatch is created it is initialized with a count. This count denotes the number of times event must occur before waiting threads can pass through the latch.

Note that a CountDownLatch initialized to N can be used either ways-

  • To make one thread wait until N threads have completed some action, or
  • Some action has been completed N times (may be by a single thread).

Each time one of these events occur count is decremented using the countdown() method of the CountDownLatch class. Waiting threads are released when the count reaches zero.

Thread(s) that are waiting for the latch to release are blocked using await() method.

Java CountDownLatch Constructor

CountDownLatch(int count)

Constructs a CountDownLatch initialized with the given count. Here count specifies the number of events that must happen in order for the latch to open.

await() and countdown() methods in CountDownLatch class

await() and countdown() are two main methods in CountDownLatch class which control the working of the latch.

await() method- A thread that waits on the latch to open calls await() method, await() method has two forms.

1. public void await() throws InterruptedException

Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted. If the current count is zero then this method returns immediately.

If the current count is greater than zero then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of two things happen:

  • The count reaches zero due to invocations of the countDown() method
  • Some other thread interrupts the current thread.

2. public boolean await(long timeout, TimeUnit unit) throws InterruptedException

Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted, or the specified waiting time elapses, the waiting time is specified by an object of TimeUnit enumeration.

If the current count is zero then this method returns immediately with the value true. If the current count is greater than zero then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happen:

  • The count reaches zero due to invocations of the countDown() method.
  • Some other thread interrupts the current thread.
  • The specified waiting time elapses.

countdown() method- Threads which are executing the events signal the completion of the event by calling countDown() method.

public void countDown()

Decrements the count of the latch, releasing all waiting threads if the count reaches zero.

CountDownLatch Java Example program

That's a lot of theory so let's see an example to make it clearer and see how await(), countdown() and the constructor to provide count are actually used.

Let's take a scenario where your application needs to read 3 files, parse the read lines and only after reading and parsing all the three files the application should move ahead to do some processing with the parsed objects.
So here we'll have three separate threads reading three separate files and the main thread awaits until all the three threads finish and call countdown().

public class CountdownlatchDemo {
  public static void main(String[] args) {
    CountDownLatch cdl = new CountDownLatch(3);
    // Initializing three threads to read 3 different files.
    Thread t1 = new Thread(new FileReader("thread-1", "file-1", cdl));
    Thread t2 = new Thread(new FileReader("thread-2", "file-2", cdl));
    Thread t3 = new Thread(new FileReader("thread-3", "file-3", cdl));
    t1.start();
    t2.start();
    t3.start();
    try {
      // main thread waiting till all the files are read
      cdl.await();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    System.out.println("Files are read ... Start further processing");
  }
}

class FileReader implements Runnable {
  private String threadName;
  private String fileName;
  private CountDownLatch cdl;
  FileReader(String threadName, String fileName, CountDownLatch cdl){
    this.threadName = threadName;
    this.fileName = fileName;
    this.cdl = cdl;        
  }
  @Override
  public void run() {
    System.out.println("Reading file " + fileName + " thread " + threadName);
    // do countdown here
    cdl.countDown();
  } 
}

Output

Reading file file-1 thread thread-1
Reading file file-3 thread thread-3
Reading file file-2 thread thread-2
Files are read ... Start further processing

Here it can be seen that inside main() method, CountDownLatch instance cdl is created with an initial count of 3. Then three instances of FileReader are created that start three new threads. Then the main thread calls await() on cdl, which causes the main thread to wait until cdl count has been decremented three times. Notice that cdl instance is passed as a parameter to the FileReader constructor that cdl instance is used to call countdown() method in order to decrement the count. Once the countdown reaches zero, the latch opens allowing the main thread to resume.

You can comment the code where await() is called, then main thread will resume even before all the 3 files are read, so you see in these type of scenarios where you want the thread to resume only after certain events occur then CountDownLatch is a powerful synchronization aid that allows one or more threads to wait for certain events to finish in other threads.

From the above example if you got the feeling that whatever count you have given in the CountDownLatch, you should spawn the same number of threads for countdown then that is a wrong understanding. As I have mentioned it depends on the number of events, so you can very well have a single thread with a loop and decrementing the count there.

Let's change the example used above to have single thread and use for loop to countdown.

public class CountdownlatchDemo {
  public static void main(String[] args) {
    CountDownLatch cdl = new CountDownLatch(3);
    // Initializing threads to read 3 different files.
    Thread t1 = new Thread(new FileReader("thread-1", "file-1", cdl));
    /*Thread t2 = new Thread(new FileReader("thread-2", "file-2", cdl));
    Thread t3 = new Thread(new FileReader("thread-3", "file-3", cdl));*/
    t1.start();
    /*t2.start();
    t3.start();*/
    try {
      // main thread waiting till all the files are read
      cdl.await();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    System.out.println("Files are read ... Start further processing");
  }
}

class FileReader implements Runnable {
  private String threadName;
  private String fileName;
  private CountDownLatch cdl;
  FileReader(String threadName, String fileName, CountDownLatch cdl){
    this.threadName = threadName;
    this.fileName = fileName;
    this.cdl = cdl;        
  }
  @Override
  public void run() {
    for(int i = 0; i < 3; i++){
      System.out.println("Reading file " + fileName + " thread " + threadName);
      // do countdown here
      cdl.countDown();
    }
  }
}

Output

Reading file file-1 thread thread-1
Reading file file-1 thread thread-1
Reading file file-1 thread thread-1
Files are read ... Start further processing

Here you can see that only a single thread is used and countdown is done on the number of events. So it is true both ways. A CountDownLatch initialized to N can be used to make one thread wait until N threads have completed some action, or some action has been completed N times.

Usage of CountDownLatch in Java

As you have seen in the example you can use CountDownLatch when you want to break your code in such a way that more than one thread can process the part of the code but you can start further processing only when all the threads which are working on some part of the code have finished. Once all the threads have finished main thread can come out of the await (as the latch is released) and start further processing.

You can also use CountDownLatch to test concurrency by giving a certain count in the CountDownLatch Constructor and start that many threads. Also there may be more than one waiting thread, so that scenario how waiting threads behave once the countdown reaches zero (as all of them will be released at once) can also be tested.

If you have some external dependencies and once all the dependencies are up and running then only you should start processing in your application. That kind of scenario can also be handled with CountDownLatch.

CountDownLatch in Java can not be reused

One point to remember is CountDownLatch cannot be reused. Once the countdown reaches zero any further call to await() method won't block any thread. It won't throw any exception either.

Let's see an example. We'll use the same example as above and spawn 3 more threads once the first three set of threads are done.

public class CountdownlatchDemo {
  public static void main(String[] args) {
    CountDownLatch cdl = new CountDownLatch(3);
    // Initializing three threads to read 3 different files.
    Thread t1 = new Thread(new FileReader("thread-1", "file-1", cdl));
    Thread t2 = new Thread(new FileReader("thread-2", "file-2", cdl));
    Thread t3 = new Thread(new FileReader("thread-3", "file-3", cdl));
    t1.start();
    t2.start();
    t3.start();
    try {
      // main thread waiting till all the files are read
      cdl.await();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    System.out.println("Files are read ... Start further processing");
    Thread t4 = new Thread(new FileReader("thread-4", "file-4", cdl));
    Thread t5 = new Thread(new FileReader("thread-5", "file-5", cdl));
    Thread t6 = new Thread(new FileReader("thread-6", "file-6", cdl));
    t4.start();
    t5.start();
    t6.start();
    try {
      // main thread waiting till all the files are read
      cdl.await();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
      System.out.println("Files are read again ... Start further processing");
  }
}

class FileReader implements Runnable {
  private String threadName;
  private String fileName;
  private CountDownLatch cdl;
  FileReader(String threadName, String fileName, CountDownLatch cdl){
    this.threadName = threadName;
    this.fileName = fileName;
    this.cdl = cdl;        
  }
  @Override
  public void run() {
    System.out.println("Reading file " + fileName + " thread " + threadName);
    // do countdown here
    cdl.countDown();
  }
}

Output

Reading file file-2 thread thread-2
Reading file file-3 thread thread-3
Reading file file-1 thread thread-1
Files are read ... Start further processing
Files are read again ... Start further processing
Reading file file-4 thread thread-4
Reading file file-6 thread thread-6
Reading file file-5 thread thread-5

Here note that await() is called again after starting thread4, thread5 and thread6 but it doesn't block main thread as it did for the first three threads. "Files are read again ... Start further processing" is printed even before the next three threads are processed. Another concurrent utility CyclicBarrier can be resued infact that is one of the difference between CountDownLatch and CyclicBarrier.

Points to note

  • A CountDownLatch initialized to N, using its constructor, can be used to make one (or more) thread wait until N threads have completed some action, or some action has been completed N times.
  • countDown() method is used to decrement the count, once the count reaches zero the latch is released.
  • await() method is used to block the thread(s) waiting for the latch to release.
  • CountDownLatch cannot be reused. Once the countdown reaches zero any further call to await() method won't block any thread.

That's all for this topic Java CountDownLatch With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Difference Between CountDownLatch And CyclicBarrier in Java
  2. ConcurrentHashMap in Java With Examples
  3. AtomicInteger in Java With Examples
  4. ConcurrentSkipListMap in Java With Examples
  5. Java Concurrency Interview Questions And Answers

You may also like-

  1. Difference Between Thread And Process in Java
  2. Java ThreadLocal Class With Examples
  3. How to remove duplicate elements from an ArrayList in Java
  4. Difference Between Comparable and Comparator in Java
  5. Creating Custom Exception Class in Java
  6. Garbage Collection in Java
  7. NodeJS NPM Package Manager
  8. Spring Batch Processing Using JDBCTemplate batchUpdate() Method

Wednesday, June 5, 2024

Java CyclicBarrier With Examples

There are scenarios in concurrent programming when you want set of threads to wait for each other at a common point until all threads in the set have reached that common point, concurrent util provides a synchronization aid CyclicBarrier in Java to handle such scenarios where you want set of threads to wait for each other to reach a common barrier point.

The barrier is called cyclic because it can be re-used after the waiting threads are released.

Note that CyclicBarrier was introduced in Java 5 along with other concurrent classes like CountDownLatch, ConcurrentHashMap, CopyOnWriteArrayList, BlockingQueue with in the java.util.Concurrent package.


CyclicBarrier class constructors

CyclicBarrier class in Java has following two constructors-

CyclicBarrier(int parties)

Creates a new CyclicBarrier that will trip when the given number of parties (threads) are waiting upon it, and does not perform a predefined action when the barrier is tripped.

CyclicBarrier(int parties, Runnable barrierAction)

Creates a new CyclicBarrier that will trip when the given number of parties (threads) are waiting upon it, and which will execute the given barrier action when the barrier is tripped, performed by the last thread entering the barrier.

Here parties parameter signifies the number of threads that must invoke await() before the barrier is tripped.

barrierAction specifies a thread that will be executed when the barrier is reached.

How CyclicBarrier is used

First thing is to create a CyclicBarrier object using any of the two constructors, specifying the number of threads that should wait for each other. When each thread reaches the barrier (common point) call await() method on the CyclicBarrier object. This will suspend the thread until all the threads call the await() method on the same CyclicBarrier object. Once all the specified threads have called await() method that will trip the barrier and all threads can resume operation.

If the current thread is the last thread to arrive, and a non-null barrier action was supplied in the constructor, then the current thread runs the action before allowing the other threads to continue.

await() method in CyclicBarrier

await() method has following two forms-

  1. public int await() throws InterruptedException, BrokenBarrierException
  2. public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException

In the second form it Waits until all parties have invoked await on this barrier, or the specified waiting time elapses.

If the current thread is not the last to arrive then it is disabled for thread scheduling purposes and lies dormant until one of the following things happens:

  • The last thread arrives; or
  • The specified timeout elapses; (In case of second form) or
  • Some other thread interrupts the current thread; or
  • Some other thread interrupts one of the other waiting threads; or
  • Some other thread times out while waiting for barrier; or
  • Some other thread invokes reset() on this barrier.

Await() method returns int which is the arrival index of the current thread, where index (Number of specified threads - 1) indicates the first to arrive and zero indicates the last to arrive.

CyclicBarrier Java example

Now is the time to see an example of CyclicBarrier in Java. Let's take a scenario where your application needs to read 3 files using 3 threads, parse the read lines and only after reading and parsing all the three files the application should call another thread for further processing. In this scenario we can use CyclicBarrier and provide a runnable action to execute thread once all the threads reach the barrier.

public class CyclicBarrierDemo {
  public static void main(String[] args) {
    CyclicBarrier cb = new CyclicBarrier(3, new AfterAction());
    // Initializing three threads to read 3 different files.
    Thread t1 = new Thread(new TxtReader("thread-1", "file-1", cb));
    Thread t2 = new Thread(new TxtReader("thread-2", "file-2", cb));
    Thread t3 = new Thread(new TxtReader("thread-3", "file-3", cb));
    t1.start();
    t2.start();
    t3.start();
    
    System.out.println("Done ");
  }
}

class TxtReader implements Runnable {
  private String threadName;
  private String fileName;
  private CyclicBarrier cb;
  TxtReader(String threadName, String fileName, CyclicBarrier cb){
    this.threadName = threadName;
    this.fileName = fileName;
    this.cb = cb;        
  }
  @Override
  public void run() {
    System.out.println("Reading file " + fileName + " thread " + threadName);    
    try{
      // calling await so the current thread suspends
      cb.await();           
    } catch (InterruptedException e) {
      System.out.println(e);
    } catch (BrokenBarrierException e) {
      System.out.println(e);
    }
  }
}

class AfterAction implements Runnable {
  @Override
  public void run() {
    System.out.println("In after action class, start further processing as all files are read");
  }
}

Output

Done 
Reading file file-2 thread thread-2
Reading file file-1 thread thread-1
Reading file file-3 thread thread-3
In after action class, start further processing as all files are read

In the code CyclicBarrier instance is created with 3 parties so the barrier will trip when 3 threads are waiting upon it.

One thing to note here is that main thread doesn't block as can be seen from the "Done" printed even before the threads start. Also it can be seen the AfterAction class is executed once all the three threads call the await() method and the barrier is tripped.

Now if you want to block the main thread then you have to call the await() on the main thread too. Let's take another CyclicBarrier example where two services are started using two separate threads and main thread should start process only after both the services are executed.

public class CBExample {
  public static void main(String[] args) {
    CyclicBarrier cb = new CyclicBarrier(3);
    // Creating two threads with CyclicBarrier obj as param
    Thread t1 = new Thread(new FirstService(cb));
    Thread t2 = new Thread(new SecondService(cb));
    System.out.println("starting threads ");
    t1.start();
    t2.start();
        
    try {
      // Calling await for main thread
      cb.await();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (BrokenBarrierException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    // once await is called for all the three threads, execution starts again
    System.out.println("In main thread, processing starts again ..... ");
    }
}

class FirstService implements Runnable {
  CyclicBarrier cb;
  FirstService(CyclicBarrier cb){
    this.cb = cb;
  }
  @Override
  public void run() {
    System.out.println("In First service, thread " + Thread.currentThread().getName());
    try {
      // Calling await for Thread-0
      cb.await();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (BrokenBarrierException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }      
  }   
}

class SecondService implements Runnable {
  CyclicBarrier cb;
  SecondService(CyclicBarrier cb){
    this.cb = cb;
  }
  @Override
  public void run() {
    System.out.println("In Second service, thread " + Thread.currentThread().getName());
    try {
      // Calling await for Thread-1
      cb.await();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (BrokenBarrierException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }    
  }    
}

Output

starting threads 
In First service, thread Thread-0
In Second service, thread Thread-1
In main thread, processing starts again .....

Here it can be seen that main thread starts only after both the services are executed.

CyclicBarrier can be reused

Unlike CountDownLatch, CyclicBarrier in Java can be reused after the waiting threads are released.

Let's reuse the same example as above where three threads were used to read 3 files. Now three more threads are added to read 3 more files and the same CyclicBarrier object is used with initial count as 3.

public class CyclicBarrierDemo {
  public static void main(String[] args) {
    CyclicBarrier cb = new CyclicBarrier(3, new AfterAction());
    // Initializing three threads to read 3 different files.
    Thread t1 = new Thread(new TxtReader("thread-1", "file-1", cb));
    Thread t2 = new Thread(new TxtReader("thread-2", "file-2", cb));
    Thread t3 = new Thread(new TxtReader("thread-3", "file-3", cb));
    
    t1.start();
    t2.start();
    t3.start();
        
    System.out.println("Start another set of threads ");
    
    Thread t4 = new Thread(new TxtReader("thread-4", "file-4", cb));
    Thread t5 = new Thread(new TxtReader("thread-5", "file-5", cb));
    Thread t6 = new Thread(new TxtReader("thread-6", "file-6", cb));
    t4.start();
    t5.start();
    t6.start();           
  }
}

class TxtReader implements Runnable {
  private String threadName;
  private String fileName;
  private CyclicBarrier cb;
  TxtReader(String threadName, String fileName, CyclicBarrier cb){
    this.threadName = threadName;
    this.fileName = fileName;
    this.cb = cb;        
  }
  @Override
  public void run() {
    System.out.println("Reading file " + fileName + " thread " + threadName);    
    try{
      // calling await so the current thread suspends
      cb.await();
        
    } catch (InterruptedException e) {
      System.out.println(e);
    } catch (BrokenBarrierException e) {
      System.out.println(e);
    }
  }
}

class AfterAction implements Runnable {
  @Override
  public void run() {
    System.out.println("In after action class, start further processing 
     as all files are read");
  }
}

Output

Start another set of threads 
Reading file file-1 thread thread-1
Reading file file-2 thread thread-2
Reading file file-3 thread thread-3
In after action class, start further processing as all files are read
Reading file file-4 thread thread-4
Reading file file-5 thread thread-5
Reading file file-6 thread thread-6
In after action class, start further processing as all files are read

Here it can be seen that specified runnableAction class is called twice as the CyclicBarrier is reused here. Note that the thread order may be different while executing the code.

Points to note

  • A CyclicBarrier initialized to N, using its constructor, can be used to make N threads wait using await() and the barrier will be broken once all the N threads call await() method.
  • A barrierAction can also be provided while creating CyclicBarrier object. This barrierAction will be executed once the barrier is tripped. This barrier action is useful for updating shared-state before any of the parties continue.
  • If the current thread is not the last to arrive then it is paused after calling await() and lies dormant until the last thread arrives, current thread or some other waiting thread is interrupted by any other thread, specified timeout elapses (as provided in await()) or some thread calls reset() method.
  • reset() method resets the barrier to its initial state. If any parties are currently waiting at the barrier, they will return with a BrokenBarrierException.
  • CyclicBarrier in Java uses an all-or-none breakage model for failed synchronization attempts: If a thread leaves a barrier point prematurely because of interruption, failure, or timeout, all other threads waiting at that barrier point will also leave abnormally via BrokenBarrierException (orInterruptedException if they too were interrupted at about the same time).

That's all for this topic Java CyclicBarrier With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Difference Between CountDownLatch And CyclicBarrier in Java
  2. Java ArrayBlockingQueue With Examples
  3. Java Semaphore With Examples
  4. Java Exchanger With Examples
  5. Java Concurrency Interview Questions And Answers

You may also like-

  1. ConcurrentHashMap in Java With Examples
  2. Volatile Keyword in Java With Examples
  3. Just In Time Compiler (JIT) in Java
  4. Optional class in Java 8
  5. Method reference in Java 8
  6. finalize method in Java
  7. How to Resolve Local Variable Defined in an Enclosing Scope Must be Final or Effectively Final Error
  8. Angular One-Way Data Binding Using String Interpolation

Tuesday, June 4, 2024

Writing a File in Node.js

In the post Reading a File in Node.js we saw how to use methods of fs module to read a file. In this post we'll see how to write a file in Node.js using the methods of the fs module.

How to write to a file in Node.js

In the fs module there are two methods to write to a file.

fs.writeFile()- This functions writes the file content in a non-blocking, asynchronous manner, replacing the file if it already exists. A callback function is provided which is called when the file write operation is completed.

fs.writeFileSync()- It is the synchronous function for writing content to a file which means it blocks while the write operation is in progress. The function returns undefined.

Apart from these two methods there is also a writeFile() function in the fs.promises API which asynchronously writes to a file and returns a Promise object which is resolved with no arguments upon success. Thus, you don't need a callback function.

Using fs.writeFile()

Syntax of fs.writeFile() method is as given below.

fs.writeFile( file, data, options, callback )
The four parameters are described below-
  1. file- Path to the file where content has to be written or file descriptor (a number returned by opening the file using the open() method).
  2. data- Content to be written to the file. It can be of type string, Buffer, TypedArray, DataView.
  3. options- It specifies optional parameters that can be provided with write operation. Type can be either string or object. Optional parameters are described below-
    • encoding- A string value specifying the encoding of the file. Default is 'utf8'
    • mode- An integer value specifying the file mode. Default is 0o666 which means both read and write.
    • flag- Flag used in write operation. Default flag is 'w' which means open file for writing, file is created if it doesn't exist or truncated if it exists.
    • flush- If all data is successfully written to the file, and flush is true, fs.fsync() is used to flush the data. Default value is false.
    • signal- Allows aborting an in-progress writeFile
  4. callback- A function that is called when the file operation completes. Takes one argument err which denotes the error that can be thrown if write operation fails.

fs.writeFile () Example

const fs = require('fs');
const path = require('path');

const content = 'Hello World from NodeJS!!';

fs.writeFile(path.join(__dirname, 'Hello.txt'), content, (err)=>{
    if(err){
        console.error('Error while writing to a file', err);
        return;
    }
});

If you want to give optional parameters then you can pass them as shown below-

const fs = require('fs');
const path = require('path');

const content = 'Hello World from NodeJS!!';

fs.writeFile(path.join(__dirname, 'Hello.txt'), content,  {
    encoding: "utf8",
    flag: "w",
    mode: 0o666
  }, (err)=>{
    if(err){
        console.error('Error while writing to a file', err);
        return;
    }
    console.log('File written Successfully');
});

Using fs.writeFileSync()

Syntax of fs.writeFileSync() method is as given below

fs.writeFileSync(file, data, options)

Description of parameters is similar to fs.writeFile()

fs.writeFileSync() Example

const fs = require('fs');
const path = require('path');

const content = 'Hello World from NodeJS!!';

try {
    fs.writeFileSync(path.join(__dirname, 'Hello.txt'), content);
    console.log('File written Successfully');
} catch (err) {
    console.error(err);
}

Using fsPromises.WriteFile()

Syntax of fsPromises.writeFile() method is as given below.

fsPromises.writeFile(file, data, options)

Description of parameters is similar to fs.writeFile() method as given above.

fsPromises.WriteFile() Example

const fs = require('fs');
const fsPromises = fs.promises;
const path = require('path');

async function writeFile(filePath) {
    try {
        const content = 'Hello World from NodeJS';
        await fsPromises.writeFile(filePath, content);
    } catch (err) {
        console.log(err);
    }
}

That's all for this topic Writing a File in Node.js. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Appending a File in Node.js
  2. NodeJS Blocking Non-blocking Code
  3. Node.js REPL
  4. NodeJS NPM Package Manager
  5. Creating HTTP server in Node.js

You may also like-

  1. Difference Between HashMap And ConcurrentHashMap in Java
  2. ConcurrentSkipListMap in Java With Examples
  3. JSX in React
  4. Ternary Operator in Python
  5. Dependency Injection in Spring Framework
  6. Spring Integration With Quartz Scheduler

Monday, June 3, 2024

Reading a File in Node.js

The fs module in Node.js provides functions to work with the file system. Using fs module functions you can create file, read file, write to a file, append to a file, delete a file and do many other I/O tasks. In this article we'll see how to read a file in Node.js using methods of fs module.

How to read file in Node.js

In the fs module there are two methods to read a file.

fs.readFile()- This functions reads the file content in a non-blocking, asynchronous manner. A callback function is provided which is called when the file read operation is completed.

fs.readFileSync()- It is the synchronous version of fs.readFile() which means it is a blocking function. Function returns the contents of the file.

Apart from these two methods there is also a readFile() function in the fs.promises API which asynchronously reads the entire contents of a file and returns a Promise object which is resolved with the contents of the file. Thus, you don't need a callback function.

Using fs.readFile()

Syntax of fs.readFile() method is as given below

fs.readFile(file[, options], callback)

The three parameters are described below-

  1. file- This is the filename or file descriptor
  2. options- The optional options argument can be a string specifying an encoding (for example ‘utf8’), or an object with an encoding property specifying the character encoding and a flag with default as 'r' which indicates open file for reading. If both values are passed as an object then it will be like this {encoding: 'utf8', flag: 'r'}.
  3. callback function- A function that is called when the file operation completes. The callback function is passed two arguments (err, data).
    • err- Encapsulates the error, if any, while reading the file.
    • data- Contents of the file.

fs.readFile () Example

const fs = require('fs');
const path = require('path');

fs.readFile(path.join(__dirname, 'Hello.txt'), 'utf8', (err, data)=>{
    if(err){
        console.error('Error while reading file', err);
        return;
    }
    console.log(data);     
});

On running this example file, it should display the content of the passed file on the console.

Using fs.readFileSync()

Syntax of fs.readFileSync() method is as given below

fs.readFile(file[, options])

Description of parameters is same as in readFile() method.

fs.readFileSync() Example

const fs = require('fs');
const path = require('path');

const data = fs.readFileSync(path.join(__dirname, 'Hello.txt'), {encoding: 'utf8', flag: 'r'})
console.log(data);

Using fsPromises.readFile()

Syntax of fsPromises.readFile() method is as given below

fsPromises.readFile(file, options)

The parameters are described below-

  1. file- This is the filename or file descriptor
  2. options- The optional options argument can be a string specifying an encoding (for example ‘utf8’), or an object with an encoding property specifying the character encoding and a flag with default as 'r' which indicates open file for reading. If both values are passed as an object then it will be like this {encoding: 'utf8', flag: 'r'}.

This method returns a Promise so async/await can be used to make the code more readable.

fsPromises.readFile() Example

const fs = require('fs');
const fsPromises = fs.promises;
const path = require('path');

async function readFile(filePath) {
  try {
    const data = await fsPromises.readFile(filePath, { encoding: 'utf8' });
    console.log(data);
  } catch (err) {
    console.log(err);
  }
}

readFile(path.join(__dirname, 'Hello.txt'));

That's all for this topic Reading a File in Node.js. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Writing a File in Node.js
  2. NodeJS Event Loop
  3. Node.js Event Driven Architecture
  4. NodeJS Blocking Non-blocking Code

You may also like-

  1. Creating HTTP server in Node.js
  2. How to Setup a Node.js Project
  3. How to Add Bootstrap to Angular Application
  4. Angular Pipes With Examples
  5. JavaScript Rest Parameter
  6. Find All Permutations of a Given String Java Program
  7. pass Statement in Python
  8. Spring Boot Microservice Example Using FeignClient

Sunday, June 2, 2024

Java Phaser With Examples

Phaser in Java is one of the synchronization aid provided in concurrency util. Phaser is similar to other synchronization barrier utils like CountDownLatch and CyclicBarrier. What sets Phaser apart is it is reusable (like CyclicBarrier) and more flexible in usage. In both CountDownLatch and CyclicBarrier number of parties (thread) that are registered for waiting can't change where as in Phaser that number can vary. Also note that Phaser has been introduced in Java 7.

Phaser in Java is more suitable for use where it is required to synchronize threads over one or more phases of activity. Though Phaser can be used to synchronize a single phase, in that case it acts more like a CyclicBarrier. But it is more suited where threads should wait for a phase to finish, then advance to next phase, wait again for that phase to finish and so on.


Java Phaser constructors

Phaser class in Java has 4 constructors

  • Phaser()- Creates a new phaser with no initially registered parties, no parent, and initial phase number 0.
  • Phaser(int parties)- Creates a new phaser with the given number of registered unarrived parties, no parent, and initial phase number 0.
  • Phaser(Phaser parent)- Creates a new phaser with the given parent with no initially registered parties.
  • Phaser(Phaser parent, int parties)- Creates a new phaser with the given parent and number of registered unarrived parties.

How Phaser in Java works

First thing is to create a new instance of Phaser.

Next thing is to register one or more parties with the Phaser. That can be done using register(), bulkRegister(int) or by specifying number of parties in the constructor.

Now since Phaser is a synchronization barrier so we have to make phaser wait until all registered parties finish a phase. That waiting can be done using arrive() or any of the variants of arrive() method. When the number of arrivals is equal to the parties which are registered that phase is considered completed and it advances to next phase (if there is any), or terminate.

Note that each generation of a phaser has an associated phase number. The phase number starts at zero, and advances when all parties arrive at the phaser, wrapping around to zero after reaching Integer.MAX_VALUE.

Methods in Java Phaser class

Some of the methods in Phaser class are as given below-

  • resgister()- Adds a new unarrived party to this phaser. It returns the arrival phase number to which this registration applied.
  • arrive()- Arrives at this phaser, without waiting for others to arrive. Note that arrive() method does not suspend execution of the calling thread. Returns the arrival phase number, or a negative value if terminated. Note that this method should not be called by an unregistered party.
  • arriveAndDeregister()- Arrives at this phaser and deregisters from it without waiting for others to arrive. Returns the arrival phase number, or a negative value if terminated.
  • arriveAndAwaitAdvance()- This method awaits other threads to arrives at this phaser. Returns the arrival phase number, or the (negative) current phase if terminated. If you want to wait for all the other registered parties to complete a given phase then use this method.
  • bulkRegister(int parties)– Used to register perties in bulk. Given number of new unarrived parties will be registered to this phaser.
  • onAdvance(int phase, int registeredParties)– If you want to perform some action before the phase is advanced you can override this method. Also used to control termination.

Java Phaser Features

1. Phaser is more flexible- Unlike the case for other barriers, the number of parties registered to synchronize on a Phaser may vary over time. Tasks may be registered at any time (using methods register(), bulkRegister(int), or by specifying initial number of parties in the constructor). Tasks may also be optionally deregistered upon any arrival (using arriveAndDeregister()).

2. Phaser termination- A Phaser may enter a termination state, that may be checked using method isTerminated(). Upon termination, all synchronization methods immediately return without waiting for advance, as indicated by a negative return value. Similarly, attempts to register upon termination have no effect.

3. Phaser Tiering- Phasers in Java may be tiered (i.e., constructed in tree structures) to reduce contention. Phasers with large numbers of parties may experience heavy synchronization contention costs. These may be set up as a groups of sub-phasers which share a common parent. This may greatly increase throughput even though it incurs greater per-operation overhead.

Phaser Java example code

Let's try to make things clearer through an example. So we'll have two phases in the application. In the first phase we have three threads reading 3 different files, parsing and storing them in DB, then in second phase 2 threads are started to query the DB table on the inserted records. Let's assume that one of the field is age in the DB table and we want to query count of those having age greater than 40 using one thread and in another thread we want to get the count of those having age less than or equal to 40.

public class PhaserDemo {

 public static void main(String[] args) {
  Phaser ph = new Phaser(1);
  int curPhase;
  curPhase = ph.getPhase();
  System.out.println("Phase in Main " + curPhase + " started");
  // Threads for first phase
  new FileReaderThread("thread-1", "file-1", ph);
  new FileReaderThread("thread-2", "file-2", ph);
  new FileReaderThread("thread-3", "file-3", ph);
  //For main thread
  ph.arriveAndAwaitAdvance();
  System.out.println("New phase " + ph.getPhase() + " started");
  // Threads for second phase
  new QueryThread("thread-1", 40, ph);
  new QueryThread("thread-2", 40, ph);
  curPhase = ph.getPhase();
  ph.arriveAndAwaitAdvance();
  System.out.println("Phase " + curPhase + " completed");
  // deregistering the main thread
  ph.arriveAndDeregister();
 }
}

class FileReaderThread implements Runnable {
 private String threadName;
 private String fileName;
 private Phaser ph;

 FileReaderThread(String threadName, String fileName, Phaser ph){
  this.threadName = threadName;
  this.fileName = fileName;
  this.ph = ph;
  ph.register();
  new Thread(this).start();
 }
 @Override
 public void run() {
  System.out.println("This is phase " + ph.getPhase());
  
  try {
   Thread.sleep(20);
   System.out.println("Reading file " + fileName + " thread " 
                           + threadName + " parsing and storing to DB ");
   // Using await and advance so that all thread wait here
   ph.arriveAndAwaitAdvance();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  ph.arriveAndDeregister();
 }
}

class QueryThread implements Runnable {
 private String threadName;
 private int param;
 private Phaser ph;
 
 QueryThread(String threadName, int param, Phaser ph){
  this.threadName = threadName;
  this.param = param;
  this.ph = ph;
  ph.register();
  new Thread(this).start();
 }
 
 @Override
 public void run() {
  
  System.out.println("This is phase " + ph.getPhase());
  System.out.println("Querying DB using param " + param 
                  + " Thread " + threadName);
  ph.arriveAndAwaitAdvance();
  System.out.println("Threads finished");
  ph.arriveAndDeregister();
 }
}

Output

Phase in Main 0 started
This is phase 0
This is phase 0
This is phase 0
Reading file file-1 thread thread-1 parsing and storing to DB 
Reading file file-2 thread thread-2 parsing and storing to DB 
Reading file file-3 thread thread-3 parsing and storing to DB 
New phase 1 started
This is phase 1
Querying DB using param 40 Thread thread-1
This is phase 1
Querying DB using param 40 Thread thread-2
Threads finished
Threads finished
Phase 1 completed

Here it can be seen that first a Phaser instance ph is created with initial party count as 1, which corresponds to the main thread.

Then in the first set of 3 threads which are used in the first phase ph object is also passed which is used for synchronization. As you can see in the run method of the FileReaderThread class arriveAndAwaitAdvance() method is used so that the threads wait there for other threads. We have registered 3 more threads after the initial main thread so arriveAndAwaitAdvance() is used in the main method too to make the main thread wait before advancing.

In the second phase another set of two threads are created which are using the same phaser object ph for synchronization.

Logic for reading the file, parsing the file and storing it in the DB is not given here. Also the queries used in the second thread are not given. The scenario used here is to explain Phaser so that's where the concentration is.

Phaser Monitoring

Phaser class in Java has several methods for monitoring. These methods can be called by any caller not only by registered parties.

  • getRegisteredParties()- Returns the number of parties registered at this phaser.
  • getArrivedParties()- Returns the number of registered parties that have arrived at the current phase of this phaser.
  • getUnarrivedParties()- Returns the number of registered parties that have not yet arrived at the current phase of this phaser.
  • getPhase()- Returns the current phase number.

Overriding onAdvance() method in Phaser

If you want to perform an action before advancing from one phase to another, it can be done by overriding the onAdvance() method of the Phaser class. This method is invoked when the Phaser advances from one phase to another.
If this method returns true, this phaser will be set to a final termination state upon advance, and subsequent calls to isTerminated() will return true.
If this method returns false, phaser will be kept alive.

onAdvance() method

protected boolean onAdvance(int phase, int registeredParties)
Here
  • phase- current phase number on entry to this method, before this phaser is advanced.
  • registeredParties- the current number of registered parties.

One of the use case to override onAdvance() method is to ensure that your phaser executes a given number of phases and then stop.

So we'll create a class called PhaserAdvance that will extend Phaser and override the onAdvance() method to ensure that specified number of phases are executed.

Overriding onAdvance() method example

public class PhaserAdvance extends Phaser{
  PhaserAdvance(int parties){
    super(parties);
  }
    
  // Overriding the onAdvance method
  @Override
  protected boolean onAdvance(int phase, int registeredParties) {
    System.out.println("In onAdvance method, current phase which is completed 
      is " + phase );
    // Want to ensure that phaser runs for 2 phases i.e. phase 1 
    // or the no. of registered parties become zero
    if(phase == 1 || registeredParties == 0){
      System.out.println("phaser will be terminated ");
      return true;
    }else{
      System.out.println("phaser will continue ");
      return false;
    }     
  }
    
  public static void main(String... args) {
    // crating phaser instance
    PhaserAdvance ph = new PhaserAdvance(1);
    // creating three threads
    new TestThread("thread-1", ph);
    new TestThread("thread-2", ph);
    new TestThread("thread-3", ph);
    
    while(!ph.isTerminated()){
      ph.arriveAndAwaitAdvance();
    }
    System.out.println("In main method, phaser is terminated");
  }
}

class TestThread implements Runnable {
  private String threadName;
  private Phaser ph;

  TestThread(String threadName, Phaser ph){
    this.threadName = threadName;
    this.ph = ph;
    // register new unarrived party to this phaser
    ph.register();
    new Thread(this).start();
  }
  @Override
  public void run() {
    // be in the loop till the phaser is terminated
    while(!ph.isTerminated()){
      System.out.println("This is phase " + ph.getPhase() + 
        " And Thread - "+ threadName);
      // Using await and advance so that all thread wait here
      ph.arriveAndAwaitAdvance();
    }      
  }
}

Output

This is phase 0 And Thread - thread-1
This is phase 0 And Thread - thread-2
This is phase 0 And Thread - thread-3
In onAdvance method, current phase which is completed is 0
phaser will continue 
This is phase 1 And Thread - thread-3
This is phase 1 And Thread - thread-2
This is phase 1 And Thread - thread-1
In onAdvance method, current phase which is completed is 1
phaser will be terminated 
In main method, phaser is terminated

Here it can be seen that a new class PhaserAdvance is created extending the Phaser class. This PhaserAdvance class overrides the onAdvance() method of the Phaser class. In the overridden onAdvance() method it is ensured that 2 phases are executed thus the if condition with phase == 1 (phase count starts from 0).

That's all for this topic Java Phaser With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Difference Between CountDownLatch And CyclicBarrier in Java
  2. Java Exchanger With Examples
  3. ConcurrentHashMap in Java With Examples
  4. Java PriorityBlockingQueue With Examples
  5. Java Concurrency Interview Questions And Answers

You may also like-

  1. Difference Between ReentrantLock and Synchronized in Java
  2. Callable and Future in Java With Examples
  3. Why wait(), notify() And notifyAll() Methods Are in Object Class And Not in Thread Class
  4. Java ThreadLocal Class With Examples
  5. How to Sort Elements in Different Order in TreeSet
  6. How ArrayList Works Internally in Java
  7. Global Keyword in Python With Examples
  8. Spring Transaction Management Example - @Transactional Annotation and JDBC

Saturday, June 1, 2024

ConcurrentHashMap in Java With Examples

ConcurrentHashMap in Java is introduced as another thread-safe alternative to Hashtable (or explicitly synchronizing the map using synchronizedMap method) from Java 5. ConcurrentHashMap class extends AbstractMap class and implements ConcurrentMap interface through which it provides thread safety and atomicity guarantees.

Why another Map

First thing that comes to mind is why another map when we already have a HashMap or HashTable. If you need to use a Map like structure with in a multi-threaded environment with thread safety you can use a Hashtable or a synchronized HashMap by using Collections.synchronizedMap() method. Then what unique does ConcurrentHashMap in Java offer?

Problem with Hashtable or synchronized Map is that all of its methods are synchronized on a common lock thus only a single thread can access it at any given time, even for read operations, making these data structures slower. ConcurrentHashMap is designed to provide better performance while providing thread safety too.


How performance is improved in ConcurrentHashMap

ConcurrentHashMap in Java is also a hash based map like HashMap, how it differs is the locking strategy used by it. Unlike HashTable (or synchronized HashMap) it doesn't synchronize every method on a common lock. ConcurrentHashMap uses separate lock for separate buckets thus locking only a portion of the Map.

If you have idea about the internal implementation of the HashMap you must be knowing that by default there are 16 buckets. Same concept is used in ConcurrentHashMap and by default there are 16 buckets and also separate locks for separate buckets. So the default concurrency level is 16.

Since there are 16 buckets having separate locks of their own which effectively means at any given time 16 threads can operate on the map concurrently, provided all these threads are operating on separate buckets. So you see how ConcurrentHashMap provides better performance by locking only the portion of the map rather than blocking the whole map resulting in greater shared access.

For locking any of the bucket independently of the other buckets the first node in the bucket is locked by using synchronized keyword. Note that before Java 8, implementation of Java ConcurrentHashMap used to have Segment array with with each segment having its own lock which has been changed from Java 8. Now the first node in the bucket itself is locked using the node's own builtin synchronized monitors.

ConcurrentHashMap Internal implementation in Java
ConcurrentHashMap implementation in Java

Further performance improvement

Performance of Java ConcurrentHashMap is further improved by providing read access concurrently without any blocking. Retrieval operations (including get) generally do not block, so may overlap with update operations (including put and remove). Retrievals reflect the results of the most recently completed update operations which may mean that retrieval operations may not fetch the current/in-progress value (Which is one drawback). Memory visibility for the read operations is ensured by volatile reads. You can see in the ConcurrentHashMap code that the val and next fields of Node are volatile.

Also for aggregate operations such as putAll and clear which works on the whole map, concurrent retrievals may reflect insertion or removal of only some entries (another drawback of separate locking). Because read operations are not blocking but some of the writes (which are on the same bucket) may still be blocking.

Constructors in Java ConcurrentHashMap

There are five constructors in the ConcurrentHashMap class-

  • ConcurrentHashMap()- Creates a new, empty map with the default initial table size (16).
  • ConcurrentHashMap(int initialCapacity)- Creates a new, empty map with an initial table size accommodating the specified number of elements without the need to dynamically resize.
  • ConcurrentHashMap(int initialCapacity, float loadFactor)- Creates a new, empty map with an initial table size based on the given number of elements (initialCapacity) and initial table density (loadFactor).
  • ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel)- Creates a new, empty map with an initial table size based on the given number of elements (initialCapacity), table density (loadFactor), and number of concurrently updating threads (concurrencyLevel).
  • ConcurrentHashMap​(Map<? extends K,? extends V> m)- Creates a new map with the same mappings as the given map.

Java ConcurrentHashMap example

At this juncture let's see a simple example where a ConcurrentHashMap is created and (key, value) pairs are added to it. Then getting the collection view of the Map it is iterated to display the stored keys and values.

public class CHMDemo {
  public static void main(String[] args) {
    // Creating ConcurrentHashMap
    Map<String, String> cityTemperatureMap = new ConcurrentHashMap<String, String>();
    
    // Storing elements
    cityTemperatureMap.put("Delhi", "24");
    cityTemperatureMap.put("Mumbai", "32");
    //cityTemperatureMap.put(null, "26");
    cityTemperatureMap.put("Chennai", "35");
    cityTemperatureMap.put("Bangalore", "22" );
    
    for (Map.Entry<String, String> e : cityTemperatureMap.entrySet()) {
      System.out.println(e.getKey() + " = " + e.getValue());
    }
  }
}

Null is not allowed in ConcurrentHashMap

Though HashMap allows one null as key but ConcurrentHashMap doesn't allow null as key. In the previous example you can uncomment the line which has null key. While trying to execute the program it will throw null pointer exception.

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class CHMDemo {
  public static void main(String[] args) {
    // Creating ConcurrentHashMap
    Map cityTemperatureMap = new ConcurrentHashMap();
    
    // Storing elements
    cityTemperatureMap.put("Delhi", "24");
    cityTemperatureMap.put("Mumbai", "32");
    // Adding null key
    cityTemperatureMap.put(null, "26");
    cityTemperatureMap.put("Chennai", "35");
    cityTemperatureMap.put("Bangalore", "22" );
    
    for (Map.Entry e : cityTemperatureMap.entrySet()) {
      System.out.println(e.getKey() + " = " + e.getValue());
    }
  }
}
Exception in thread "main" java.lang.NullPointerException
 at java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011)
 at java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1006)
 at org.netjs.prog.CHMDemo.main(CHMDemo.java:16)

Atomic operations in ConcurrentHashMap

ConcurrentHashMap in Java provides a lot of atomic methods, let's see it with an example how these atomic methods help. Note that from Java 8 many new atomic methods are added.

Suppose you have a word Map that counts the frequency of every word where key is the word and count is the value, in a multi-threaded environment, even if ConcurrentHashMap is used, there may be a problem as described in the code snippet.

public class CHMAtomicDemo {
  public static void main(String[] args) {
    ConcurrentHashMap<String, Integer> wordMap = new ConcurrentHashMap<>();
    ..
    ..
    // Suppose one thread is interrupted after this line and 
    // another thread starts execution
    Integer prevValue = wordMap.get(word); 
    
    Integer newValue = (prevValue == null ? 1 : prevValue + 1);
    // Here the value may not be correct after the execution of 
    // both threads
    wordMap.put(word, newValue);  
  }
}

To avoid these kind of problems you can use atomic method, one of the atomic method is compute which can be used here.

wordMap.compute(word, (k,v)-> v == null ? 1 : v + 1);

If you see the general structure of the Compute method

compute(K key, BiFunction<? super K,? super V,? extendsV> remappingFunction)
Here BiFunction functional interface is used which can be implemented as a lambda expression.

So here rather than having these lines-

Integer prevValue = wordMap.get(word); 
Integer newValue = (prevValue == null ? 1 : prevValue + 1);
wordMap.put(word, newValue);
you can have only this line
wordMap.compute(word, (k,v)-> v == null ? 1 : v + 1);

The entire method invocation is performed atomically. Some attempted update operations on this map by other threads may be blocked while computation is in progress.

There are several other atomic operations like computeIfAbsent, computeIfPresent, merge, putIfAbsent.

Fail-safe iterator in ConcurrentHashMap

Iterator returned by the Java ConcurrentHashMap is fail-safe which means it will not throw ConcurrentModificationException. It can be seen in the example code where a new (key, value) pair is added while the map is iterated, still it doesn't throw ConcurrentModificationException.

public class CHMDemo {
  public static void main(String[] args) {
    // Creating ConcurrentHashMap
    Map<String, String> cityTemperatureMap = new ConcurrentHashMap<String, String>();
    
    // Storing elements
    cityTemperatureMap.put("Delhi", "24");
    cityTemperatureMap.put("Mumbai", "32");
    cityTemperatureMap.put("Chennai", "35");
    cityTemperatureMap.put("Bangalore", "22" );
    
    Iterator<String> iterator = cityTemperatureMap.keySet().iterator();   
    while (iterator.hasNext()){
      System.out.println(cityTemperatureMap.get(iterator.next()));
      // adding new value, it won't throw error
      cityTemperatureMap.put("Kolkata", "34");        
    }
  }
}

Output

24
35
34
32
22

According to the JavaDocs- The view's iterator is a "weakly consistent" iterator that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.

When is ConcurrentHashMap a better choice

ConcurrentHashMap is a better choice when there are more reads than writes. As mentioned above retrieval operations are non-blocking so many concurrent threads can read without any performance problem. If there are more writes and that too many threads operating on the same segment then the threads will block which will deteriorate the performance.

Points to note

  • ConcurrentHashMap in Java is also a hash based map like HashMap, but ConcurrentHashMap is thread safe.
  • In ConcurrentHashMap thread safety is ensured by having separate locks for separate buckets, resulting in better performance.
  • In ConcurrentHashMap class, by default the bucket size is 16 and the concurrency level is also 16.
  • Null keys are not allowed in Java ConcurrentHashMap.
  • Iterator provided by the ConcurrentHashMap is fail-safe, which means it will not throw ConcurrentModificationException.
  • Retrieval operations (like get) don't block so may overlap with update operations (including put and remove).

That's all for this topic ConcurrentHashMap in Java With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Difference Between HashMap And ConcurrentHashMap in Java
  2. CopyOnWriteArrayList in Java With Examples
  3. How HashMap Works Internally in Java
  4. Java CountDownLatch With Examples
  5. Java Concurrency Interview Questions And Answers

You may also like-

  1. How to Iterate a HashMap of ArrayLists of String in Java
  2. How to Sort HashSet in Java
  3. Difference Between Comparable and Comparator in Java
  4. Try-With-Resources in Java With Examples
  5. static reference to the non-static method or field error
  6. Race Condition in Java Multi-Threading
  7. Angular Reactive Form Validation Example
  8. Spring MVC Radiobutton And Radiobuttons Form Tag Example

Friday, May 31, 2024

Java Exception Handling Interview Questions And Answers

In this post interview questions and answers for exception handling in Java are listed. This compilation will help the Java developers in preparing for their interviews.

  1. What is Exception Handling?

    Exception Handling in Java provides a way to handle a situation when an exception is thrown and shows a meaningful message to the user and continue with the flow of the program.

    When an exceptional condition occurs with in a method, the method (where the exception occurred) creates an Exception Object and throws it. The created exception object contains information about the error, its type and the state of the program when the error occurred.

    The method where the exception is thrown may handle that exception itself or pass it on. In case it passes it on, run time system goes through the method hierarchy that had been called to get to the current method to search for a method that can handle the exception.

    Five keywords used to manage Java exception handling

    • try- Any code that might throw an exception is enclosed within a try block.
    • catch- If an exception occurs in try block, catch block can provide exception handlers to handle it in a rational manner.
    • finally- The finally block always executes when the try block exits. So, any code that must execute after a try block is completed should be put in finally block.
    • throw- throw is used to manually thrown an exception.
    • throws- Any exception that is thrown in a method but not handled there must be specified in a throws clause.
    Read more about Exception handling in Java here.

  2. Explain the exception hierarchy in Java?

    Throwable class is the super class of all the exception types. Below Throwable class there are two subclasses which denotes two distinct branches of exceptions-

    • Exception- An Exception indicates that a problem has occurred, but it is not a serious system problem. The user programs you write will throw and catch Exceptions.
    • Error- It defines exceptions that are not expected to be caught by your program. Exceptions of type Error are used by the Java run-time system to indicate errors having to do with the run-time environment, itself.
      Examples of error are StackOverflowError, OutOfMemoryError etc.
    • Below Exception there is a distinct subclass RunTimeExcpetion- RunTimeExcpetion and its descendants denote the exceptional conditions that are external to the application, and the application usually cannot anticipate or recover from them.

    Read more about exception hierarchy in Java here.

  3. What is the difference between Checked Exception and Unchecked Exception?

    Checked Exception is a direct subclass of Exception where as unchecked exception is a subclass of RunTimeException.

    Checked exception should be wrapped in a try-catch block or specified as throws clause where as there is no such requirement for unchecked exception.

    Failure to provide exception handling mechanism for checked exception result in compiler error whereas no compile time error for unchecked exception.

    Checked exceptions are designed to reduce the number of exceptions which are not properly handled and where there is a reasonable chance for recovery. UnCheckedExceptions are mostly programming errors.

    Read more about difference between Checked Exception and Unchecked Exception here.

  4. What is the difference between error and exception?

    Exception- An Exception indicates that a problem has occurred, but it is not a serious system problem. The user programs you write will throw and catch Exceptions.

    Error- It defines exceptions that are not expected to be caught by your program. Exceptions of type Error are used by the Java run-time system to indicate errors having to do with the run-time environment, itself.
    Examples of error are StackOverflowError, OutOfMemoryError etc.


  5. Is it necessary that each try block must be followed by a catch block?

    No it is not mandatory that there should be a catch block after a try block. try block can have only a matching finally block. So there are these valid combinations try-catch-finally, try-catch, try-finally.

    Read more about try-catch block here.

  6. What is finally block?

    When an exception occurs in the code, the flow of the execution may change or even end abruptly. That may cause problem if some resources were opened in the method.
    For example, if a file was opened in a method and it was not closed in the end as some exception occurred then the resources may remain open consuming memory. finally provides that exception-handling mechanism to clean up.

    Code with in the finally block will be executed after a try/catch block has completed. The finally block will be executed whether or not an exception is thrown.

    Read more about finally block here.

  7. Is it possible to have a finally block without catch?

    Yes we can have a try-finally block, catch is optional. We can have these combinations try-catch-finally, try-catch, try-finally.

    Read more about finally block here.

  8. Are you aware of any scenario when finally will not be executed?

    According to Java docs. If the JVM exits (By explicitly using System.exit() or a JVM crash) while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.

    Read more about finally here.

  9. What is a nested try statement?

    A try-catch-finally block can reside inside another try-catch-finally block that is known as nested try statement.

    public class NestedTryDemo {
      public static void main(String[] args) {
        try{
          System.out.println("In Outer try block");
          try{
            System.out.println("In Inner try block");
            int a = 7 / 0;
          }catch (IllegalArgumentException e) {
            System.out.println("IllegalArgumentException caught");
          }finally{
            System.out.println("In Inner finally");
          }
        }catch (ArithmeticException e) {
          System.out.println("ArithmeticException caught");
        }finally {
          System.out.println("In Outer finally");
        }
      }
    }
    
    Read more about nested try statement here.

  10. What are multiple catch blocks?

    There might be a case when a code enclosed with in a try block throws more than one exception. To handle these types of situations, two or more catch clauses can be specified where each catch clause catches a different type of exception. When an exception is thrown, each of the catch statement is inspected in order, and the first one whose type matches that of the thrown exception is executed.

    int a[] = {0};
    try{
      int b = 7/a[i];
    }catch(ArithmeticException aExp){
      aExp.printStackTrace();
    }catch(ArrayIndexOutOfBoundsException aiExp){
      aiExp.printStackTrace();
    }
    
    Read more about multiple catch blocks here.

  11. What is exception propagation?

    When an exceptional condition occurs within a method, the method (where the exception occurred) creates an Exception Object and throws it. The created exception object contains information about the error, its type and the state of the program when the error occurred.
    The method where the exception is thrown may handle that exception itself or pass it on. In case it passes it on, run time system goes through the method hierarchy that had been called to get to the current method to search for a method that can handle the exception.
    If your program is not able to catch any particular exception, that will ultimately be processed by the default handler. This process of going through the method stack is known as Exception propagation.

    Read more about exception propagation here.

  12. What is throw keyword?

    It is possible for a Java program to throw an exception explicitly that is done using the throw statement.

    The general form of throw is-
    throw throwableObject;

    We can get this throwableObject in 2 ways-
    • By using the Exception parameter of catch block.
    • Create a new one using the new operator.
    try{
       throw new NullPointerException();   
      }catch(NullPointerException nExp){
       System.out.println("Exception caught in catch block of displayValue");
       throw nExp;
      }
     }
    
    Read more about throw keyword here.

  13. What is throws clause?

    If in a method we don't want to handle any exception but want to leave it to the calling method to handle any exception that is thrown by the called method, it is done using throws keyword.

    Using throws a method can just declare the exception it may throw and callers of the method have to provide exception handling for those exceptions (or they can also declare them using throws).

    General form of a method declaration that includes a throws clause

    type method-name(parameter-list) throws exception-list
    {
    // body of method
    }
    
    Here, exception-list is a comma-separated list of the exceptions that a method can throw.
    Read more about throws clause here.

  14. Difference between throw and throws?

    • throw is used to throw an exception.
    • throws is used to declare an exception, in the method signature, that can be thrown from a method.
    Read more about difference between throw and throws here.

  15. final Vs finally Vs finalize

    • final- final keyword is used to restrict in some way. It can be used with variables, methods and classes. When a variable is declared as final, its value can not be changed once it is initialized. Except in case of blank final variable, which must be initialized in the constructor.
      If you make a method final in Java, that method can't be overridden in a sub class.
      If a class is declared as final then it can not be sub classed.
    • finally- finally is part of exception handling mechanism in Java. finally block is used with try-catch block. finally block is always executed whether any exception is thrown or not and raised exception is handled in catch block or not. Since finally block always executes thus it is primarily used to close the opened resources like database connection, file handles etc.
    • finalize()- finalize() method is a protected method of java.lang.Object class. Since it is in Object class thus it is inherited by every class. This method is called by garbage collector thread before removing an object from the memory. This method can be overridden by a class to provide any cleanup operation and gives object final chance to cleanup before getting garbage collected.
      protected void finalize() throws Throwable
      {
        //resource clean up operations
      }
      
    Read more about final Vs finally Vs finalize here.

  16. What are the rules of exception handling with respect to method overriding?

    There are certain restrictions while overriding a method in case of exception handling in Java. Broadly there are two rules-

    • If superclass method has not declared any exception using throws clause then subclass overridden method can't declare any checked exception though it can declare unchecked exception.
    • If superclass method has declared an exception using throws clause then subclass overridden method can do one of the three things.
      • sub-class can declare the same exception as declared in the super-class method.
      • subclass can declare the subtype exception of the exception declared in the superclass method. But subclass method can not declare any exception that is up in the hierarchy than the exception declared in the super class method.
      • subclass method can choose not to declare any exception at all.
    Read more about exception handling and method overriding here.

  17. What is the error in the following code?

    class Parent{
       public void displayMsg() throws IOException{
         System.out.println("In Parent displayMsg()");
        throw new IOException("Problem in method - displayMsg - Parent");
       }
    }
    public class ExceptionOverrideDemo extends Parent{
      public void displayMsg() throws Exception{  
        System.out.println("In ExceptionOverrideDemo displayMsg()"); 
        throw new Exception("Problem in method - displayMsg - ExceptionOverrideDemo");
      }  
    }
     

    Here parent class had declared IOException where as subclass has declared Exception. Exception is the super class of IOException thus it is wrong according to the rules of method overriding and exception handling. Thus the code will give compiler error.

    Read more about exception handling and method overriding here.

  18. What is multi-catch statement in Java 7?

    Before Java 7 multi-catch statement, if two or more exceptions were handled in the same way, we still had to write separate catch blocks for handling them.

    catch(IOException exp){
      logger.error(exp);
      throw exp;
    }catch(SQLException exp){
      logger.error(exp);
      throw exp;
    }
    

    With Java 7 and later it is possible to catch multiple exceptions in one catch block, which eliminates the duplicated code. Each exception type within the multi-catch statement is separated by Pipe symbol (|).

    catch(IOException | SQLException exp){
      logger.error(exp);
      throw exp;
    }
    
    Read more about multi-catch statement in Java 7 here.

  19. What is try-with-resources or ARM in Java 7?

    Java 7 introduced a new form of try known as try-with-resources for Automatic Resource Management (ARM). Here resource is an object that must be closed after the program is finished with it. Example of resources would be an opened file handle or database connection etc.

    Before the introduction of try-with-resources we had to explicitly close the resources once the try block completes normally or abruptly.

    try {
        br = new BufferedReader(new FileReader("C:\\test.txt"));
        System.out.println(br.readLine());
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
      try {
        if (br != null){
          System.out.println("Closing the file");
          br.close();
        }                
      } catch (IOException ex) {
        ex.printStackTrace();
      }
    }
    

    try-with-resources helps in reducing such boiler plate code. Let's see the same example using try-with-resources.

    try(BufferedReader br = new BufferedReader(new FileReader("C:\\test.txt"))) {            
      System.out.println(br.readLine());
    } catch (IOException e) {
      e.printStackTrace();
    } 
    
    Read more about try-with-resources in Java 7 here.

  20. When is custom exception class needed? How to create a custom exception class?

    According to Java Docs, you should write your own exception classes if you answer yes to any of the following questions; otherwise, you can probably use someone else's.

    • Do you need an exception type that isn't represented by those in the Java platform?
    • Would it help users if they could differentiate your exceptions from those thrown by classes written by other vendors?
    • Does your code throw more than one related exception?
    • If you use someone else's exceptions, will users have access to those exceptions? A similar question is, should your package be independent and self-contained?
    Read more about creating custom exception class here.

  21. What is the difference Between StackOverflowError and OutOfMemoryError in Java?

    StackOverflowError- Whenever you run any Java program even if you don’t explicitly create any thread a main thread is started and that thread runs the program. For each thread JVM creates a stack, whenever any method is invoked a new frame is created and pushed into the JVM stack for the thread. Each frame stores data corresponding to the invoked method including local variables, operand stack and a reference to the run-time constant pool and reference to exception table. Once the method execution is completed corresponding stack frame is popped out of the stack.
    JVM throws StackOverflowError if the stack memory requirement of any method exceeds the permitted stack memory size.

    OutOfMemoryError- In Java, memory for each object, for arrays and for instance variables (variables at class level not method level) is created on the heap. When there are no references to an object that object is garbage collected thus clearing the heap memory. If you try to create an object or array that tries to take more memory than the allocated heap memory or there are a lot of objects in heap that are still referenced so can’t be garbage collected and JVM tries to allocate heap memory for a new object JVM throws java.lang.OutOfMemoryError because there is no sufficient heap memory.

    Read more about difference Between StackOverflowError and OutOfMemoryError here.

Related Topics

  1. Java Multithreading Interview Questions And Answers
  2. Java Collections Interview Questions And Answers
  3. Java String Interview Questions And Answers
  4. Core Java Basics Interview Questions And Answers
  5. Java OOP Interview Questions And Answers
  6. Java Concurrency Interview Questions And Answers
  7. Java Lambda Expressions Interview Questions And Answers
  8. Java Stream API Interview Questions And Answers