April 25, 2024

Java Volatile Keyword With Examples

In this post we’ll see what is volatile keyword in Java, when to use volatile variable and what is the reason for declaring variable as volatile.

What is volatile keyword in Java

To know volatile keyword in Java better you would have to know a little about the optimizations that happens for the variables with in the Java memory model. Let’s say you have a variable test declared in your code. You would think that test variable will be stored only in RAM and all the threads will read the value of the test variable from there. But the processors, in order to make processing faster, would hold the value of the variable in its cache. In that case any change to the value is written back to the main memory only when the synchronization between the cache and the memory happens.

That will cause problem where multiple threads are reading or writing a shared variable. If we take our example of test variable which is used among multiple threads, there may be a scenario that one thread has made changes to test variable which is still stored in cache and another thread tries to read the value of test variable from the main memory. That will result in memory inconsistency errors as different threads will read/write different values of test variable.

volatile keyword in java

How declaring variable as volatile in Java helps

Declaring a variable as volatile ensures that value of the variable is always read from the main memory. So declaring a field as volatile in Java gives visibility guarantee that a write to a volatile field happens-before every subsequent read of that field.

Problem we saw above because of value being cached by the CPU will not happen with volatile field as it is guaranteed that updates done by thread-1 to the volatile variable will always be visible to thread-2.

Volatile Java example code

One of the most common use of the volatile keyword in Java is boolean status flags declared as volatile, where the flag indicates completion of event so that another thread can start.

Let’s first see what will happen if volatile is not used in such case.

public class VolatileDemo {
  private static  boolean flag = false;
  public static void main(String[] args) {
    // Thread-1
    new Thread(new Runnable(){
      @Override
      public void run() {
        for (int i = 1; i <= 2000; i++){
          System.out.println("value - " + i);
        }
        // changing status flag
        flag = true;
        System.out.println("status flag changed " + flag );
      }			
    }).start();
    // Thread-2
    new Thread(new Runnable(){		
      @Override
      public void run() {
        int i = 1;
        while (!flag){
          i++;
        }
        System.out.println("Start other processing " + i);    
      }
    }).start();
  }
}
Output
....
....
value - 1997
value - 1998
value - 1999
value - 2000
status flag changed true

On running this code you will see that the first thread displays value of i till 2000 and change the status flag but the second thread won’t print the message "Start other processing " and the program won’t terminate. Since flag variable is accessed frequently in the thread-2 in the while loop, the compiler may optimize by placing the value of flag in a register, then it will keep testing the loop condition (while (!flag)) without reading the value of flag from main memory.

Now if you change the boolean variable flag and mark it as volatile that will guarantee that the change done to the shared variable by one thread is visible to other threads.

private static volatile boolean flag = false;
Output
....
....
value - 1997
value - 1998
value - 1999
value - 2000
status flag changed true
Start other processing 68925258

Volatile also ensures reordering of statements doesn’t happen

When a thread reads a volatile variable, it not only sees the latest change to the volatile, but also the side effects of the code that led up the change. That is also known as the happens before extended guarantee which is provided by volatile keyword from Java 5.

For example, If thread T1 changes other variables before updating the volatile variable then thread T2 will get the updated variable of those variables too that were changed before the update of volatile variable in thread T1.

That brings us to the point of reordering that may happen at compile-time for optimizing the code. The code statements may be reordered as long as the semantic meaning is not changed.

private int var1;
private int var2;
private volatile int var3;
public void calcValues(int var1, int var2, int var3){
  this.var1 = 1;
  this.var2 = 2;
  this.var3 = 3;
}

Since var3 is volatile so, because of happens-before extended guarantee, updated values of var1 and var2 will also be written to main memory and visible to other threads.

What if these statements are re-ordered for optimization.

this.var3 = 3;
this.var1 = 1;
this.var2 = 2;

Now the values of variables var1 and var2 are updated after update of volatile variable var3. So the updated values of these variables var1 and var2 may not be available to other threads.

That is why reordering is not permitted if read or write of volatile variable happens after the update to other variables.

Volatile ensures visibility not atomicity

In the scenario where only one thread is writing to a variable and other thread is just reading (like in case of status flag) volatile helps in the correct visibility of the value of the variable. But volatile is not enough if many threads are reading and writing the value of the shared variable. In that case because of race condition threads may still get wrong values.

Let's clear it with a  Java example in which there is a class SharedData whose object is shared among the thread. With in the SharedData class counter variable is marked as volatile. Four threads are created that increment the counter and then display the updated value. Because of the race condition threads may still get wrong values. Note that you may get the correct values also in few runs.

public class VolatileDemo implements Runnable {
  SharedData obj = new SharedData();
  public static void main(String[] args) {
    VolatileDemo vd = new VolatileDemo();
    new Thread(vd).start();
    new Thread(vd).start();
    new Thread(vd).start();
    new Thread(vd).start();
  }

  @Override
  public void run() {
    obj.incrementCounter();
    System.out.println("Counter for Thread " + Thread.currentThread().getName() + 
        " " + obj.getCounter());
  }	
}

class SharedData{
  public volatile int counter = 0;
  public int getCounter() {
    return counter;
  }

  public void incrementCounter() {
    ++counter;
  }
}
Output
Counter for Thread Thread-0 1
Counter for Thread Thread-3 4
Counter for Thread Thread-2 3
Counter for Thread Thread-1 3

Important points about volatile in Java

  • Volatile keyword in Java can only be used with variables not with methods and classes.
  • A variable marked as volatile ensures that the value is not cached and the updates to the volatile variables are always done in main memory.
  • Volatile also ensures that the reordering of the statements don’t happen that way volatile provides happens-before extended guarantee where changes to other variables before the update of volatile variables are also written to main memory and visible to other threads.
  • Volatile ensures just visibility not the atomicity.
  • It is a compile-time error if a final variable is also declared volatile.
  • Using volatile is less expensive than using lock.

That's all for the topic Java Volatile Keyword With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

April 24, 2024

HTTP GET Method in React - fetch, Axios

In web application we need to use HTTP requests to call APIs to do CRUD operations. Most used HTTP methods for these operations are- GET, PUT, POST, PATCH, DELETE. In this post we'll see how to use HTTP GET method from React applications in order to get resources from a server.

React Example HTTP GET method

In this example we'll see usage of both fetch() method in Fetch API and Axios.

  • fetch()- This method is used to call APIs across the network. GET is the default for fetch method. Though the name is fetch() but don't get confused it can be used for POST, DELETE, PUT, PATCH operations too.
    With fetch() method you pass the path to the resource you want to fetch and it returns a promise that resolves with a Response object.
  • Axios- It is a promise-based HTTP Client for node.js and the browser.

For API calls JSONPlaceholder is used which is a free fake API for testing and prototyping.

Using HTTP GET method in React with fetch

fetch() method takes one mandatory argument; path to the resource (API), it also accepts a second parameter, an init object that allows you to control a number of different settings. Here is the fetch method format for a POST request where you need to explicitly specify the method you are using and the object that you want to send.

fetch(url, {
    method: "POST", // *GET, POST, PUT, DELETE, etc.
    mode: "cors", // no-cors, *cors, same-origin
    cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
    credentials: "same-origin", // include, *same-origin, omit
    headers: {
      "Content-Type": "application/json",
      // 'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: JSON.stringify(data), // body data type must match "Content-Type" header
  });

Since GET method is default for fetch and no object has to be sent so second parameter is not needed, we just need to pass the URL to connect to API for fetching resource.

In the example there are two Components- Posts and PostItem.

Posts component does the job of fetching posts (limited to 10 posts). For that fetch() method is used which returns a Promise, using promise chaining first the response object is converted to JSON data and then set to the Posts state. There is also a catch part to handle the scenario when the Promise is rejected.

Posts.js

import { useEffect, useState } from "react";
import PostItem from "./PostItem";

const Posts = () => {
  // initially empty array of posts
  const [posts, setPosts] = useState([]);
  useEffect(()=>{
    fetch('https://jsonplaceholder.typicode.com/posts?_limit=10')
    .then((response) => response.json())
    .then((resData) => setPosts(resData))
    .catch((error) => console.log(error.message))
  }, [])

  return (
    <div className="container">
      <h2 className="text-info text-center">Posts</h2>
      {posts.map((post) => 
          <PostItem key={post.id} post={post}></PostItem>
      )}
    </div>
  )
}

export default Posts;

In the code-

  1. useState() hook is used to maintain Posts state variable.
  2. fetch() method is called with in the useEffect() hook, that way you avoid an infinite loop. If you don’t wrap the fetch() in useEffect the setting of state variable- setPosts(resData) will result in state change and re-rendering and the same thing repeated again and again. With the useEffect() hook call will happen only once because the dependency array (second argument in useEffect()) is empty.
  3. Once posts are fetched post data is sent to PostItem component to display the post data.
  4. Note that Bootstrap 5 is used for styling here. Refer Installing Bootstrap in React to know how to install Bootstrap in your React application.

PostItem.js

const PostItem = (props) => {
  return (
    <>
      <h3>{props.post.title}</h3> 
      <span>{props.post.body}</span>
    </>
  );
}

export default PostItem;

Using async/await with fetch

Using async/await is easier than using Promise directly so that is the preferred way. You can use try/catch to handle errors with async/await.

import { useEffect, useState } from "react";
import PostItem from "./PostItem";

const Posts = () => {
  // initially empty array of posts
  const [posts, setPosts] = useState([]);
  useEffect(()=>{
    const postData = async () => {
      try{
        const response = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=10');
        // check for any error
        if(!response.ok){
          throw new Error('Error while fetching post data');
        }
        const responseData = await response.json();
        setPosts(responseData);
      }catch(error){
        console.log(error.message);
      }
    }
    postData();
  }, []);

  return (
    <div className="container">
      <h2 className="text-info text-center">Posts</h2>
      {posts.map((post) => 
        <PostItem key={post.id} post={post}></PostItem>
      )}
    </div>
  )
}
export default Posts;

In the code, note the following-

  1. Async is not directly used in useEffect function. You write a separate function with in useEffect() and make that async. That way you don’t affect the cleanup function which may otherwise never get called.
  2. Check for the response status and throw an error if response status is not ok.
  3. You need to explicitly call the async function you have written within useEffect() as done by calling postData();

Showing error message With React HTTP GET example

In the above React fetch method example with async/await error message is logged to the console. If you want to display the error to the user then you can create one more component for Error.

ErrorMessage.js

Uses the Bootstrap alert to show the error message.

const ErrorMessage = (props) => {
  return(
    <>
      <div className="alert alert-warning alert-dismissible fade show" role="alert">
        <p>{props.message}</p>
              
        <button type="button" className="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
      </div>
    </>
  )
}
export default ErrorMessage;

Posts.js

Updated to have Error state variable and the logic to show error.

import { useEffect, useState } from "react";
import ErrorMessage from "./ErrorMessage";
import PostItem from "./PostItem";

const Posts = () => {
  // initially empty array of posts
  const [posts, setPosts] = useState([]);
  const [error, setError] = useState();
  useEffect(()=>{
    const postData = async () => {
      try{
        const response = await fetch('https://jsonplaceholder.typicode.com/postsss?_limit=10');
        // check for any error
        if(!response.ok){
            throw new Error('Error while fetching post data');
        }
        const responseData = await response.json();
        setPosts(responseData);
      }catch(error){
        setError(error);
      }
    }
    postData();
  }, []);

  if(error){
    return (
      <ErrorMessage message={error.message}></ErrorMessage>
    )
  }
  return (
    <div className="container">
      <h2 className="text-info text-center">Posts</h2>
      {posts.map((post) => 
          <PostItem key={post.id} post={post}></PostItem>
      )}
    </div>
  )
}

export default Posts;

Using HTTP GET method in React with Axios

If you want to use Axios library to make HTTP calls then the first thing is to install the Axios library.

Using npm

$ npm install axios

Using yarn

$ yarn add axios

Axios returning Promise - React Example

import axios from "axios";
import { useEffect, useState } from "react";
import ErrorMessage from "./ErrorMessage";
import PostItem from "./PostItem";

const Posts = () => {
  // initially empty array of posts
  const [posts, setPosts] = useState([]);
  const [error, setError] = useState();
  useEffect(()=>{
    axios.get('https://jsonplaceholder.typicode.com/posts?_limit=10')
    .then((response) => setPosts(response.data))
    .catch((error) => setError(error))
  }, []);

  if(error){
    return (
      <ErrorMessage message={error.message}></ErrorMessage>
    )
  }
  return (
    <div className="container">
      <h2 className="text-info text-center">Posts</h2>
      {posts.map((post) => 
          <PostItem key={post.id} post={post}></PostItem>
      )}
    </div>
  )
}
export default Posts;

Some points to note here-

  1. Axios returns a Promise that resolves to a response object which has a data property containing the fetched data.
  2. (response) => setPosts(response.data)
    
  3. With Axios default behavior is to reject every response that returns with a status code that falls out of the range of 2xx and treat it as an error.
  4. Error message gives a quick summary of the error message and the status it failed with.
  5. There is no change in other 2 components PostItem and ErrorMessage. Please refer the above example to get the code for these components.

Using async/await with Axios - React Example

import axios from "axios";
import { useEffect, useState } from "react";
import ErrorMessage from "./ErrorMessage";
import PostItem from "./PostItem";

const Posts = () => {
  // initially empty array of posts
  const [posts, setPosts] = useState([]);
  const [error, setError] = useState();
  useEffect(()=>{
    const postData = async () => {
      try{
        const response = await axios.get('https://jsonplaceholder.typicode.com/posts?_limit=10');
        setPosts(response.data);
      }catch(error){
        setError(error);
      }
    }
    postData();
  }, []);

  if(error){
    return (
      <ErrorMessage message={error.message}></ErrorMessage>
    )
  }
  return (
    <div className="container">
      <h2 className="text-info text-center">Posts</h2>
      {posts.map((post) => 
          <PostItem key={post.id} post={post}></PostItem>
      )}
    </div>
  )
}

export default Posts;

That's all for the topic HTTP GET Method in React - fetch, Axios. If something is missing or you have something to share about the topic please write a comment.


You may also like

April 23, 2024

ThreadLocal Class in Java With Examples

In a multi-threaded environment a shared object would need synchronization to avoid corruption through concurrent access, but synchronization is expensive. Another alternative is to give each thread its own instance and avoid sharing of data. That’s what ThreadLocal class in Java does.

ThreadLocal class in Java provides thread local variables where each thread has its own, independently initialized copy of the variable.

How to create and access thread-local variables

Using ThreadLocal() constructor you can create a thread local variable. For example if you want to create a thread local variable that stores an integer value for individual threads.

private static final ThreadLocal<Integer> tcValue = new ThreadLocal<Integer>();

Here note that ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread.

To get or set value to this thread local variable you can use get() and set() methods of the ThreadLocal class.

tcValue.set(1);
Integer threadId = tcValue.get();

You can use initialValue() method to return the current thread's "initial value" for this thread-local variable. This method will be invoked the first time a thread accesses the variable with the get() method. The default implementation of initialValue() in the ThreadLocal class just returns null.

If you want your thread-local variables to have an initial value other than null you need to subclass ThreadLocal and override initialValue() method.

Java 8 onward withInitial(Supplier<? extends S> supplier) method can also be used to create a thread local variable. Since this method uses Supplier functional interface as parameter so lambda expression can be used to implement it.

Here is a code snippet that puts these methods to use to make it clearer.

private static final AtomicInteger nextId = new AtomicInteger(0);

// Thread local variable with initialValue() implementation to 
//return initial value to each thread
private static final ThreadLocal threadId =
  new ThreadLocal() {
    @Override 
    protected Integer initialValue() {
      return nextId.getAndIncrement();
    }
  };

If you are using withInitial() method then you can replace initialValue() implementation with the following code.

private static final ThreadLocal<Integer> threadId  = 
     ThreadLocal.withInitial(()-> {return nextId.getAndIncrement();});

Java ThreadLocal class example

1- One use of ThreadLocal class is in the scenario where you want to associate state with each thread (user ID or Transaction ID). In that case you can assign thread-local variable to each thread with a unique value. Just to verify assigned IDs are displayed again in another method.

import java.util.concurrent.atomic.AtomicInteger;

class UniqueIdGenerator{
  private static final AtomicInteger nextId = new AtomicInteger(0);
  // ThreadLocal variable
  private static final ThreadLocal<Integer> threadId = new ThreadLocal<Integer>() {
    @Override 
    protected Integer initialValue() {
     return nextId.getAndIncrement();
    }
  };
  // Returns the current thread's unique ID, assigning it if necessary
  public static int getId() {
    return threadId.get();
  }
}
public class ThreadClassDemo implements Runnable{
  @Override
  public void run() {
    System.out.println("Thread " + Thread.currentThread().getName() 
        + " Value - " +  UniqueIdGenerator.getId());
    ThreadClassDemo td = new ThreadClassDemo();
    // display stored Id again to verify
    td.displayThreadId();
  }
	
  public void displayThreadId(){
    System.out.println("Thread " + Thread.currentThread().getName() 
          + " Stored Value - " +  UniqueIdGenerator.getId());
  }
  public static void main(String[] args) {
    //ThreadClassDemo td = new ThreadClassDemo();
    Thread thread1 = new Thread(new ThreadClassDemo());
    Thread thread2 = new Thread(new ThreadClassDemo());
    Thread thread3 = new Thread(new ThreadClassDemo());
    Thread thread4 = new Thread(new ThreadClassDemo());
    Thread thread5 = new Thread(new ThreadClassDemo());
    thread1.start();
    thread2.start();
    thread3.start();
    thread4.start();
    thread5.start();
  }
}
Output
Thread Thread-3 Value - 2
Thread Thread-0 Value - 0
Thread Thread-2 Value - 4
Thread Thread-4 Value - 3
Thread Thread-1 Value - 1
Thread Thread-1 Stored Value - 1
Thread Thread-4 Stored Value - 3
Thread Thread-2 Stored Value - 4
Thread Thread-0 Stored Value - 0
Thread Thread-3 Stored Value – 2

2- You can also use ThreadLocal as an alternative to synchronizing the code as synchronization is costly. When you use SimpleDateFormat in a multi-threaded environment you do need to synchronize it as instance of SimpleDateFormat is not thread safe. Using ThreadLocal you can construct instance of SimpleDateFormat per thread. Since each thread will have its own instance local to that thread so no chance of interference by another thread.

import java.text.SimpleDateFormat;
import java.util.Date;

class DateFormatInstance{
  // ThreadLocal variable
  private static final ThreadLocal<SimpleDateFormat> threadLocalDateFmt = 
      ThreadLocal.withInitial(()-> {return new SimpleDateFormat("dd/MM/yyyy");});

  public static SimpleDateFormat getFormat() {
    return threadLocalDateFmt.get();
  }
}
public class ThreadClassDemo implements Runnable{
  @Override
  public void run() {
    System.out.println(Thread.currentThread().getName() + " Date formatter pattern is - " 
      + DateFormatInstance.getFormat().toPattern());
    System.out.println("Formatted date - " 
      + DateFormatInstance.getFormat().format(new Date()));
  }
	
  public static void main(String[] args) {
    //ThreadClassDemo td = new ThreadClassDemo();
    Thread thread1 = new Thread(new ThreadClassDemo());
    Thread thread2 = new Thread(new ThreadClassDemo());
    Thread thread3 = new Thread(new ThreadClassDemo());

    thread1.start();
    thread2.start();
    thread3.start();
  }
}
Output
Thread-1 Date formatter pattern is - dd/MM/yyyy
Thread-2 Date formatter pattern is - dd/MM/yyyy
Thread-0 Date formatter pattern is - dd/MM/yyyy
Formatted date - 10/05/2018
Formatted date - 10/05/2018
Formatted date - 10/05/2018

Important points about ThreadLocal in Java

  1. Thread-local variable is local to a thread. Each thread has its own, independently initialized copy of the variable.
  2. Each thread has global access to its own thread-local variable. If a thread is calling several methods, thread-local variable can be accessed in all of those methods.
  3. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread
  4. Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible; after a thread goes away, all of its copies of thread-local instances are subject to garbage collection (unless other references to these copies exist).

Reference:https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/lang/ThreadLocal.html

That's all for the topic ThreadLocal Class in Java With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

April 22, 2024

How to Read Input From Console in Java

If you have to read input from console in Java there are 3 options.

  1. Using BufferedReader class. See example.
  2. Using Scanner class, available from Java 5. See example.
  3. Using System.console() method, available from Java 6. See example.

Using BufferedReader class to get user input

By wrapping the standard input stream "System.in" in an InputStreamReader which is further wrapped with in a BufferedReader you can read input from console in Java.

public class ConsoleReader {
  public static void main(String[] args) {
    // Wrapping InputStreamReader and System.in
    BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
    System.out.print("Enter City Name: ");            
    try {            
      String cityName = bufferRead.readLine();
      System.out.println("Entered city name- " + cityName);
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
Output
Enter City Name: Delhi
Entered city name- Delhi

Using Scanner class to get user input in Java

Another option to read input from console in Java is to use Scanner class. A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace. The resulting tokens may then be converted into values. For scanning input there are convenient methods for different data types like nextInt(), nextDouble(), nextFloat() etc.

public class ConsoleReader {
  public static void main(String[] args) {
    System.out.print("Enter Values: ");                             
    Scanner sc = new Scanner(System.in);
    System.out.println("Entered Line- " + sc.nextLine());
    System.out.println("Entered integer value- " + sc.nextInt());
    System.out.println("Entered double value- " + sc.nextInt());
    sc.close();
  }
}
Output
Enter Values: Delhi
Entered Line- Delhi
56 67.89
Entered integer value- 56
Entered double value- 67.89

Using System.console method to get user input

You can also use System.console to read input from console in Java. One of the advantage of using System.console() method is that it returns a Console object which has a method readPassword() which can be used for reading a password or passphrase from the console with echoing disabled.

public class ConsoleReader {
  public static void main(String[] args) {
    //Using System.console()
    String username = System.console().readLine("Enter City Name: ");   
    System.out.println("Entered city name- " + username); 
  }
}
Output
Enter City Name: Delhi
Entered city name- Delhi
Using System.console method to read password
public class ConsoleReader {
  public static void main(String[] args) {
    //Using System.console()
    System.out.print("Enter password: ");
    char[] username = System.console().readPassword();   
    System.out.println("Entered password- " + username.toString()); 
  }
}
Output
Enter password:
Entered password- [C@75bd9247

As you can see echoing for the password is disabled.

That's all for the topic How to Read Input From Console in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like

HTTP DELETE Method in React - fetch, Axios

In this post we'll see how to use HTTP DELETE method in React applications in order to delete resources from a server. We'll see how to use fetch method in Fetch API and Axios to make DELETE requests with the help of examples.

fetch()- This method is used to call APIs across the network. GET is the default for fetch method.

With fetch() method you pass the URI and the body in case of PUT and POST and it returns a promise that resolves with a Response object.

Fetch syntax for DELETE method

fetch('url', {
  method: 'DELETE',
}) 
.then(response => response.json())
.then(data => console.log(data))
.catch((error) => console.log(error.message));

Axios- It is a promise-based HTTP Client for node.js and the browser. To make a DELETE request using Axios, you can use the axios.delete() method.

axios.delete(url[, config])

For API calls JSONPlaceholder is used which is a free fake API for testing and prototyping.

DELETE request in React with fetch returning Promise

For the delete example we'll use the GET example showed in this post- HTTP GET Method in React - fetch, Axios as base example which gets the 10 posts.

When displaying these posts delete button is also added with each post item now. On clicking the delete button respective post should get deleted.

HTTP DELETE Method in React

In the example there are two Components- Posts and PostItem.

Posts component does the job of fetching posts (limited to 10 posts) and that is done in the useEffect() hook.

PostItem component is used to display the fetched posts, so PostItem component acts as a presentational component.

posts.js

import axios from "axios";
import { useEffect, useState } from "react";
import PostItem from "./PostItem";

const Posts = () => {
  // initially empty array of posts
  const [posts, setPosts] = useState([]);
  useEffect(()=>{
    axios.get('https://jsonplaceholder.typicode.com/posts?_limit=10')
    .then((response) => setPosts(response.data))
    .catch((error) => console.log("Error", error.message))
  }, []);

  const deletePost = (postId)=> {
    console.log('In delete post', postId);
    const url = 'https://jsonplaceholder.typicode.com/posts/' + postId;
    console.log(url);
    fetch(url, { method: 'DELETE' })
    .then(response => {
      console.log(response);
      if (!response.ok) {
        throw new Error('Error while deleting post data');
      }
    })
    .then(() => {
      console.log('Deleted Post Successfully...');
      // Filter out the deleted post so that it is not displayed
      const updatedPosts = posts.filter(post => post.id !== postId);  
      setPosts(updatedPosts);
    })
    .catch((error) => console.log("Error", error.message));
  }
    
  return (
    <div className="container">
      <h2 className="text-info text-center">Posts</h2>
      {posts.map((post) => 
          <PostItem key={post.id} post={post} onDeleteHandler={deletePost}></PostItem>
      )}
    </div>
  )
}

export default Posts;

In the code-

  1. useState() hook is used to maintain Posts state variable.
  2. fetch() method to get posts is called with in the useEffect() hook.
  3. deletePost() function has the logic to delete the post. In the URL, postId of the post that has to be deleted is added.
  4. Fetch method is called with method as ‘DELETE’ to delete the resource.
  5. From the fetch method a Promise is returned. In the then chaining you first check if the response is ok or not. If it is not an error is thrown that will be handled by catch. If response if ok then you filter out the post that has been deleted.
  6. Note that Bootstrap 5 is used for styling here. Refer Installing Bootstrap in React to know how to install Bootstrap in your React application.
  7. For displaying posts, post data is sent to the PostItem component that shows the parent to child component communication in React.
  8. For deleting post, even is sent from PostItem component that shows the child component to parent component communication in React.

postitem.js

const PostItem = (props) => {
  const onDeleteHandler = () => {
    props.onDeleteHandler(props.post.id);       
  }
  return (
    <>
      <h3>{props.post.title}</h3> 
      <div>
        <span>{props.post.body}</span>
        <div className="text-end">
          <button className="btn btn-danger" onClick={onDeleteHandler}>Delete</button>
        </div>
      </div>
    </>
  );
}

export default PostItem;

As you can see React props are used to get data from parent component and to communicate with the parent too.

DELETE request using async/await with fetch

You can also use async/await to wait for completion of DELETE request rather than using Promise with .then chaining. Use of async/await makes the code more readable. You can use try/catch to handle errors with async/await.

Posts.js

import axios from "axios";
import { useEffect, useState } from "react";
import PostItem from "./PostItem";

const Posts = () => {
  // initially empty array of posts
  const [posts, setPosts] = useState([]);
  //const [error, setError] = useState();
  useEffect(()=>{
    axios.get('https://jsonplaceholder.typicode.com/posts?_limit=10')
    .then((response) => setPosts(response.data))
    .catch((error) => console.log("Error", error.message))
  }, []);

  const deletePost = async (postId)=> {
    console.log('In delete post', postId);
    try{
      const url = 'https://jsonplaceholder.typicode.com/posts/' + postId;
      const response = await fetch(url, { method: 'DELETE' });
      if (!response.ok) {
        throw new Error('Error while deleting post data');
      }
      //const resData = await response.json(); 
      console.log('Deleted Post Successfully');
      const updatedPosts = posts.filter(post => post.id !== postId);  
      setPosts(updatedPosts);
    }catch(error){
      console.log(error.message);
    }
  }
    
  return (
    <div className="container">
      <h2 className="text-info text-center">Posts</h2>
      {posts.map((post) => 
        <PostItem key={post.id} post={post} onDeleteHandler={deletePost}></PostItem>
      )}
    </div>
  )
}

export default Posts;

There is no change in the other component PostItem so it can be used as shown in the above example.

Few points to note in the code-

  1. deletePost() method is async.
  2. You need to wait for the response so await is used with the fetch method.
  3. Check for the response status and throw an error if response status is not ok.
  4. Code is enclosed in try/catch block to handle the thrown error.

DELETE request using async/await with error message

In the above React fetch method example with async/await, error message is logged to the console. If you want to display the error to the user then you can create one more component for Error. In the Posts component have the state for Error and set the Error in case one is thrown.

ErrorMessage.js

Uses the Bootstrap alert to show the error message.

const ErrorMessage = (props) => {
  return(
    <>
      <div className="alert alert-warning alert-dismissible fade show" role="alert">
        <p>{props.message}</p>
              
        <button type="button" className="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
      </div>
    </>
  )
}
export default ErrorMessage;

posts.js

import axios from "axios";
import { useEffect, useState } from "react";
import ErrorMessage from "./ErrorMessage";
import PostItem from "./PostItem";

const Posts = () => {
  // initially empty array of posts
  const [posts, setPosts] = useState([]);
  const [error, setError] = useState();
  useEffect(()=>{
    axios.get('https://jsonplaceholder.typicode.com/posts?_limit=10')
    .then((response) => setPosts(response.data))
    .catch((error) => setError(error))
  }, []);

  const deletePost = async (postId)=> {
    console.log('In delete post', postId);
    try{
      const url = 'https://jsonplaceholder.typicode.com/posts/' + postId;
      const response = await fetch(url, { method: 'DELETE' });
      if (!response.ok) {
        throw new Error('Error while deleting post data');
      }
      console.log('Deleted Post Successfully');
      const updatedPosts = posts.filter(post => post.id !== postId);  
      setPosts(updatedPosts);
    }catch(error){
      setError(error);
    }
  }

  if(error){
    return (
      <ErrorMessage message={error.message}></ErrorMessage>
    )
  }
    
  return (
    <div className="container">
      <h2 className="text-info text-center">Posts</h2>
      {posts.map((post) => 
        <PostItem key={post.id} post={post} onDeleteHandler={deletePost}></PostItem>
      )}
    </div>
  )
}

export default Posts;

Now in case something goes wrong while deleting a post you'll get an error message.

delete async await

Using HTTP DELETE method in React with Axios

If you want to use Axios library to make HTTP calls then the first thing is to install the Axios library.

Using npm

$ npm install axios

Using yarn

$ yarn add axios

DELETE request using Axios returning Promise - React Example

We'll use the same example as used with fetch method where we have two Components named Posts and PostItem.

import axios from "axios";
import { useEffect, useState } from "react";
import ErrorMessage from "./ErrorMessage";
import PostItem from "./PostItem";

const Posts = () => {
  // initially empty array of posts
  const [posts, setPosts] = useState([]);
  const [error, setError] = useState();
  useEffect(()=>{
    axios.get('https://jsonplaceholder.typicode.com/posts?_limit=10')
    .then((response) => setPosts(response.data))
    .catch((error) => setError(error))
  }, []);

  const deletePost = (postId)=> {
    console.log('In delete post', postId);
    const url = 'https://jsonplaceholder.typicode.com/posts/' + postId;
    axios.delete(url, { method: 'DELETE' })
        .then(resData => console.log('Deleted Post Successfully ', resData.data))
        .then(()=>{
          const updatedPosts = posts.filter(post => post.id !== postId);  
          setPosts(updatedPosts);
        })
        .catch(error => setError(error));
  }

  if(error){
    return (
      <ErrorMessage message={error.message}></ErrorMessage>
    )
  }
    
  return (
    <div className="container">
      <h2 className="text-info text-center">Posts</h2>
      {posts.map((post) => 
        <PostItem key={post.id} post={post} onDeleteHandler={deletePost}></PostItem>
      )}
    </div>
  )
}

export default Posts;

Some points to note here-

  1. Axios returns a Promise that resolves to a response object which has a data property containing the fetched data.
  2. With Axios default behavior is to reject every response that returns with a status code that falls out of the range of 2xx and treat it as an error.
  3. Error message gives a quick summary of the error message and the status it failed with.
  4. There is no change in ErrorMessage component. Please refer the above example to get the code for ErrorMessage component.

DELETE request using Axios With async/await - React Example

Here is the same example which uses async/await rather than using Promise with .then chaining. You can use try/catch to handle errors with async/await.

import axios from "axios";
import { useEffect, useState } from "react";
import ErrorMessage from "./ErrorMessage";
import PostItem from "./PostItem";

const Posts = () => {
  // initially empty array of posts
  const [posts, setPosts] = useState([]);
  const [error, setError] = useState();
  useEffect(()=>{
    axios.get('https://jsonplaceholder.typicode.com/posts?_limit=10')
    .then((response) => setPosts(response.data))
    .catch((error) => setError(error))
  }, []);

  const deletePost = async (postId)=> {
    console.log('In delete post', postId);
    try{
      const url = 'https://jsonplaceholder.typicode.com/posts/' + postId;
      const response = await axios.delete(url, { method: 'DELETE' });

      console.log('Deleted Post Successfully');
      const updatedPosts = posts.filter(post => post.id !== postId);  
      setPosts(updatedPosts);

    }catch(error){
      setError(error);
    }
  }

  if(error){
    return (
      <ErrorMessage message={error.message}></ErrorMessage>
    )
  }
    
  return (
    <div className="container">
      <h2 className="text-info text-center">Posts</h2>
      {posts.map((post) => 
        <PostItem key={post.id} post={post} onDeleteHandler={deletePost}></PostItem>
      )}
    </div>
  )
}

export default Posts;

There is no change in the other component PostItem so it can be used as shown in the above example.

That's all for the topic HTTP DELETE Method in React - fetch, Axios. If something is missing or you have something to share about the topic please write a comment.


You may also like

April 21, 2024

Java Stream - Get Last Element

In this tutorial we’ll see what options are there to get the last element of the stream using the Java Stream API.

1. Using reduce() method

reduce method in the Java Stream API is used to perform a reduction on the elements of the stream so that the stream is reduced to a single value. Thus it can be used to reduce the stream to a last value.

import java.util.Arrays;
import java.util.List;

public class StreamLastDemo {

  public static void main(String[] args) {
    List<Integer> numList = Arrays.asList(6, 10, 5, 6, 7, 8, 12);
    int lastElement = numList.stream().reduce((f, s) -> s).orElse(-1);
    System.out.println("Last element in the Stream- " + lastElement);
  }
}
Output
Last element in the Stream- 12

2. Using skip() method

You can also use skip method to skip to the last element and then return that element. This approach is not very efficient though.

public class StreamLastDemo {

  public static void main(String[] args) {
    List<Integer> numList = Arrays.asList(6, 10, 5, 6, 7, 8, 12, 22);
    // get the stream element count
    long elementCount = numList.stream().count();
    int lastElement = -1;
    // Return -1 if not able to find last element
    if(elementCount != 0) {
      lastElement = numList.stream().skip(elementCount - 1)
                        .findFirst()
                        .orElseThrow(()->new RuntimeException("Exception Occurred"));
    }
    System.out.println("Last element in the Stream: " + lastElement);
  }
}

Output
Last element in the Stream: 22

3. Using Streams.findLast() method of Guava library

In Guava library there is a Streams class with many utility methods to be used with Stream instances. There is a findLast() method to get the last element of the stream.

import java.util.Arrays;
import java.util.List;
import com.google.common.collect.Streams;

public class StreamLastDemo {

  public static void main(String[] args) {
    List numList = Arrays.asList(6, 10, 5, 6, 7, 8, 12, 22);
    int lastElement = Streams.findLast(numList.stream()).orElse(-1);
    System.out.println("Last element in the Stream: " + lastElement);
  }
}
Output
Last element in the Stream: 22

That's all for the topic Java Stream - Get Last Element. If something is missing or you have something to share about the topic please write a comment.


You may also like

April 17, 2024

Thread Starvation in Java

In a multi-threaded environment access to shared resources is synchronized so that at any given time only a single thread can enter a synchronized context. Theoretically all the threads trying to gain access to a synchronized block or method should get some CPU time periodically but in practice that may not happen. If a thread is unable to gain regular access to shared resources and is unable to make progress it is called thread starvation in Java multi-threading.

Why does thread starvation happen

Thread starvation may happen because of the following reasons.
  1. Suppose an object has a synchronized method that requires some heavy processing and takes long time to return. If one thread invokes this method frequently, other threads that also need frequent synchronized access to the same object will often be blocked.
  2. Threads with higher priority are scheduled to run first and taking all the CPU time causing the thread with minimum priority to keep on waiting to be scheduled to run.
  3. In a synchronized context even if wait method is used to relinquish object’s lock, one of the waiting thread never gets a chance to enter the synchronized context as some other threads are notified and scheduled to run.

Thread starvation Java Example

Let us try to create a scenario when thread starvation in Java may happen using the reasons as stated above.

In the code thread t1 has been assigned the maximum thread priority and it calls the synchronized method thrice. Where as thread t2 has been assigned the minimum thread priority and it calls the synchronized method only once but it has to wait for all the three calls of thread t1 to execute the synchronized method.

class MyRunnable implements Runnable{
  ThreadDemo td;
  MyRunnable(ThreadDemo td){
    this.td = td;
  }
  @Override
  public void run() {
    td.testMethod();
    td.testMethod();
    td.testMethod();
  }	
}

class AnotherRunnable implements Runnable{
  ThreadDemo td;
  AnotherRunnable(ThreadDemo td){
    this.td = td;
  }
  @Override
  public void run() {
    td.testMethod();
  }	
}

public class ThreadDemo {
  public synchronized void testMethod(){
    try {
      System.out.println("Doing some heavy processing for thread " + 
        Thread.currentThread().getName());
      Thread.sleep(300);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
	
  public static void main(String[] args) {		
    ThreadDemo td = new ThreadDemo();
    Thread t1 = new Thread(new MyRunnable(td), "t1");
    Thread t2 = new Thread(new AnotherRunnable(td), "t2");

    t1.setPriority(Thread.MAX_PRIORITY);
    t2.setPriority(Thread.MIN_PRIORITY);

    t1.start();
    t2.start();
  }
}
Output
Doing some heavy processing for thread t1
Doing some heavy processing for thread t1
Doing some heavy processing for thread t1
Doing some heavy processing for thread t2

That's all for the topic Thread Starvation in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like