How do I create JPA EntityManagerFactory?

In this code snippet you will learn how to create JPA EntityManagerFactory. This factory enable you to create the EntityManager which will be used to execute the JPA command to manipulate the database tables.

To create the EntityManagerFactory you need to create to persistence.xml file first. The file is where you configure the JPA. This file must be placed inside the META-INF directory in your program working directory.

Here is an example of the persistence.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">

    <persistence-unit name="music" transaction-type="RESOURCE_LOCAL">
        <class>org.kodejava.jpa.entity.Artist</class>
        <class>org.kodejava.jpa.entity.Genre</class>
        <class>org.kodejava.jpa.entity.Label</class>
        <class>org.kodejava.jpa.entity.Record</class>
        <class>org.kodejava.jpa.entity.Review</class>
        <class>org.kodejava.jpa.entity.Reviewer</class>
        <class>org.kodejava.jpa.entity.Track</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/musicdb" />
            <property name="javax.persistence.jdbc.user" value="music" />
            <property name="javax.persistence.jdbc.password" value="s3cr*t" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
    </persistence-unit>

</persistence>

The persistence unit defined in the persistence.xml file contains a set of entities object. We also define some properties related to the database connections including the JDBC driver class, JDBC url, the username and password for opening the connection to database.

After defining the persistence.xml file we’ll create a simple program to create the EntityManagerFactory. To create the factory we can use the javax.persistence.Persistence class createEntityManagerFactory() method and pass the persistence unit name as the parameter. In this example the persistence unit name is music as can be seen in the persistence.xml file.

After we have the factory object created we can then create an EntityManager by calling the createEntityManager() of the factory object. Let’s see the code snippet below.

package org.kodejava.jpa;

import org.kodejava.jpa.entity.Artist;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class EntityManagerFactoryExample {
    public static final String PERSISTENCE_UNIT_NAME = "music";

    public static void main(String[] args) {
        EntityManagerFactory factory =
                Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
        EntityManager manager = factory.createEntityManager();

        // Do something with the entity manager.
        Artist artist = manager.find(Artist.class, 1L);
        System.out.println("artist = " + artist);
    }
}

The Artist entity class definition.

package org.kodejava.jpa.entity;

import javax.persistence.*;
import java.io.Serial;
import java.io.Serializable;
import java.util.Objects;

@Entity
@Table(name = "artist")
public class Artist implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    private Long id;
    private String name;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "name", length = 100, nullable = false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Artist artist = (Artist) o;
        return Objects.equals(id, artist.id) &&
                Objects.equals(name, artist.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }

    @Override
    public String toString() {
        return "Artist{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

Our project directory structure.

├─ pom.xml
└─ src
   └─ main
      ├─ java
      │  └─ org
      │     └─ kodejava
      │        └─ jpa
      │           ├─ EntityManagerFactoryExample.java
      │           └─ entity
      │              ├─ Artist.java
      │              ├─ Genre.java
      │              ├─ Label.java
      │              ├─ Record.java
      │              ├─ Review.java
      │              ├─ Reviewer.java
      │              └─ Track.java
      └─ resources
         └─ META-INF
            └─ persistence.xml

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>javax.persistence</groupId>
        <artifactId>javax.persistence-api</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.6.9.Final</version>
    </dependency>
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <version>8.1.0</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I create entity object in JPA?

This example show you a simple example of an entity object used for mapping database table into Java object. The entity is a Plain Old Java Object (POJO). The JPA specification doesn’t mandate the class to extends or implements other class or interfaces.

A class which going to be persisted in a database must be annotated with the javax.persistence.Entity annotation (@Entity). As you can see in the Record class below.

By default, the mapped table name equals to the class name. But if your table name is different to your class name you can use the @Table annotation. Set the table name using the name attribute of this annotation. This annotation is also located in the javax.persistence package.

package org.kodejava.jpa.entity;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "record")
public class Record implements Serializable {
}

In JPA metadata can be added either in the class fields or using the getters or setters methods. Choose one option because you cannot mix both of them in the same entity object. Here we will annotate the getters of the class.

To define the primary key of the entity we use the @Id annotation. The @GeneratedValue annotation is used to define how the primary key of the entity should be generated. For example in this example the strategy is defined as GenerationType.IDENTITY. In MySQL database this is implemented as an auto-increment column.

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

The fields of the entity by default will be persisted into corresponding fields in the database table. If you don’t want the entity fields to be persisted you must add the @Transient annotation to it. If your entity field name is different with table field you can use the @Column annotation to define the column name and other attributes of the column such as the length, the uniqueness of the field and the not-null attribute.

To define relationship between entity object you can use annotation such as @OneToOne, @OneToMany, @ManyToOne and @ManyToMany. This annotation represent the relationship between database tables in the Java objects.

@Column(nullable = false, length = 50)
public String getTitle() {
    return title;
}

@Column(name = "release_date")
public Date getReleaseDate() {
    return releaseDate;
}

@ManyToOne
@JoinColumn(nullable = false)
public Artist getArtist() {
    return artist;
}

Below is the complete class for the Record entity. This will hold information about music record. This entity has relationship with other entity such the Artist and Label entity.

package org.kodejava.jpa.entity;

import javax.persistence.*;
import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Entity
@Table(name = "record")
public class Record implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    private Long id;
    private String title;
    private Date releaseDate;
    private Artist artist;
    private Label label;

    private List<Track> trackList = new ArrayList<>();

    public Record() {
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    @Column(nullable = false, length = 50)
    public String getTitle() {
        return title;
    }

    @Column(name = "release_date")
    public Date getReleaseDate() {
        return releaseDate;
    }

    @ManyToOne
    @JoinColumn(nullable = false)
    public Artist getArtist() {
        return artist;
    }

    @ManyToOne
    @JoinColumn(nullable = false)
    public Label getLabel() {
        return label;
    }

    @OneToMany(mappedBy = "record")
    public List<Track> getTrackList() {
        return trackList;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setReleaseDate(Date releaseDate) {
        this.releaseDate = releaseDate;
    }

    public void setArtist(Artist artist) {
        this.artist = artist;
    }

    public void setLabel(Label label) {
        this.label = label;
    }

    public void setTrackList(List<Track> trackList) {
        this.trackList = trackList;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Record record = (Record) o;
        return Objects.equals(id, record.id) &&
                Objects.equals(title, record.title) &&
                Objects.equals(releaseDate, record.releaseDate);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, title, releaseDate);
    }

    @Override
    public String toString() {
        return "Record{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", releaseDate=" + releaseDate +
                '}';
    }
}

Maven Dependencies

<dependency>
    <groupId>javax.persistence</groupId>
    <artifactId>javax.persistence-api</artifactId>
    <version>2.2</version>
</dependency>

Maven Central

What is JPA (Java Persistence API)?

JPA is a Java specification for object-relational mapping (ORM) in Java. JPA provide a way to map Java objects to database tables. This allows programmers to manipulate database information directly using Java objects instead of executing database SQL queries.

Developer can choose one of many available JPA specification implementation libraries such as Hibernate, Apache OpenJPA and EclipseLink. EclipseLink is the reference implementation of the JPA specification. In the examples that we are going to provide you in this website, Hibernate library will be used as the persistence provider.

In JPA we model our database tables into a Java objects. This Java objects also called as entity objects. The entity represent a table in database. A single row in a database table will be represented in an instance of the entity. This entity objects hold information about the mapping between objects and database tables. This information or metadata can be defined using an annotation or an XML mapping files.

Here is a simple example of entity object and its metadata information.

package org.kodejava.jpa.entity;

import javax.persistence.*;
import java.io.Serial;
import java.io.Serializable;
import java.util.Objects;

@Entity
@Table(name = "genre")
public class Genre implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    private Long id;
    private String name;

    public Genre() {
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    @Column(nullable = false, length = 50)
    public String getName() {
        return name;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Genre genre = (Genre) o;
        return Objects.equals(id, genre.id) &&
                Objects.equals(name, genre.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }

    @Override
    public String toString() {
        return "Genre{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

In the entity above we use annotation such as @Entity, @Table, @Id, @GeneratedValue and @Column. These are some annotations that you can use for object mapping.

Beside manipulating database tables using objects, JPA also provide a SQL-like queries that can be used to create a static or dynamic query statement.

Maven Dependencies

<dependency>
    <groupId>javax.persistence</groupId>
    <artifactId>javax.persistence-api</artifactId>
    <version>2.2</version>
</dependency>

Maven Central

How do I do math operations using Spring EL?

As we know that the simplest value that can be expressed in the Spring EL is a literal value such as number. Furthermore, we can also do math operations using the Spring EL. The spring configuration below show you how can do math operations using the Spring Expression Language. These operations include:

  • Add operation (+)
  • Subtract operation (-)
  • Multiply operation (*)
  • Divide operations (/)
  • Modulo operation (%)
  • Power operation (^)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="myBean" class="org.kodejava.spring.core.el.MyBean">
        <property name="total" value="#{50 + 50}" />
        <property name="length" value="#{100 - 10}" />
        <property name="size" value="#{10 * 10}" />
        <property name="reminder" value="#{10 % 3}" />
        <property name="distance" value="#{1000 / 10}" />
        <property name="power" value="#{2 ^ 10}" />
    </bean>

</beans>

The configuration above requires a bean / pojo called MyBean. It’s a simple class with some fields and getters and setters. Followed later by a simple class called SpELMathOperationDemo that demonstrate the Spring EL math operations.

package org.kodejava.spring.core.el;

public class MyBean {
    private int total;
    private int length;
    private int size;
    private float distance;
    private int reminder;
    private int power;

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public float getDistance() {
        return distance;
    }

    public void setDistance(float distance) {
        this.distance = distance;
    }

    public int getReminder() {
        return reminder;
    }

    public void setReminder(int reminder) {
        this.reminder = reminder;
    }

    public int getPower() {
        return power;
    }

    public void setPower(int power) {
        this.power = power;
    }
}
package org.kodejava.spring.core.el;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpELMathOperationDemo {
    public static void main(String[] args) {
        try (ClassPathXmlApplicationContext context =
                     new ClassPathXmlApplicationContext("spel-math-operation.xml")) {
            MyBean bean = (MyBean) context.getBean("myBean");
            System.out.println("bean.getTotal()    = " + bean.getTotal());
            System.out.println("bean.getLength()   = " + bean.getLength());
            System.out.println("bean.getSize()     = " + bean.getSize());
            System.out.println("bean.getReminder() = " + bean.getReminder());
            System.out.println("bean.getDistance() = " + bean.getDistance());
            System.out.println("bean.getPower()    = " + bean.getPower());
        }
    }
}

And these are the output printed out by the code snippet:

bean.getTotal()    = 100
bean.getLength()   = 90
bean.getSize()     = 100
bean.getReminder() = 1
bean.getDistance() = 100.0
bean.getPower()    = 1024

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I call static method using Spring EL?

In this example you will learn how to call static method using Spring EL. The T() operator of the Spring EL can be used to call static method. First, create the following class, NumberGenerator. This class has a single property randomNumber and getter / setter method.

package org.kodejava.spring.core.el;

public class NumberGenerator {
    private int randomNumber;

    public int getRandomNumber() {
        return randomNumber;
    }

    public void setRandomNumber(int randomNumber) {
        this.randomNumber = randomNumber;
    }
}

Now, create the following spring configuration file and save it in a file called SpELStatic.xml. In this configuration we register a bean called bean of type NumberGenerator. We set its randomNumber property using the value produced by the java.lang.Math.random() static method. For calling a static method we use the Spring EL T() operator, for example #{T(java.lang.Math).random()}.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="bean" class="org.kodejava.spring.core.el.NumberGenerator">
        <property name="randomNumber" value="#{T(java.lang.Math).random() * 100 + 1}" />
    </bean>

</beans>

The program below load the spring configuration and get the NumberGenerator bean to create a random number.

package org.kodejava.spring.core.el;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class StaticELDemo {
    public static void main(String[] args) {
        try (ClassPathXmlApplicationContext context =
                     new ClassPathXmlApplicationContext("spel-static.xml")) {

            NumberGenerator number = (NumberGenerator) context.getBean("bean");
            System.out.println("Random number: " + number.getRandomNumber());
        }
    }
}

And example result you might get when running the program:

Random number: 33

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I handle or avoid null value in Spring EL?

In this example you will learn how to avoid a null value, which causing a NullPointerException thrown in a Spring EL expression. To avoid this from happening we can use the null-safe accessor, using the ?. operator.

We are using the previous example, How do I inject bean’s property using Spring EL? classes, which are the Student class and the Grade class. What we need is to create a new spring configuration file to demonstrate this feature. So, here is the configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="student" class="org.kodejava.spring.core.el.Student">
        <property name="name" value="Alice" />
        <property name="grade" value="#{grade.getName()?.toUpperCase()}" />
    </bean>

    <bean id="grade" class="org.kodejava.spring.core.el.Grade">
        <property name="name">
            <null />
        </property>
        <property name="description" value="A beginner grade." />
    </bean>

</beans>

The use of null-safe accessor can be seen on the student bean’s grade property. We are calling the grade.getName() method and convert it to uppercase. We deliberately set the grade.name property to null. Calling toUpperCase on a null value will throw the NullPointerException. But because we are using the null-safe accessor the exception is not thrown, because the expression will not execute the code after the null-safe accessor. In this case when getName() return null, the toUpperCase() method will never get called.

Below is the demo program code:

package org.kodejava.spring.core.el;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpELNullSafeExpressionDemo {
    public static void main(String[] args) {
        try (ClassPathXmlApplicationContext context =
                     new ClassPathXmlApplicationContext("spel-null-safe.xml")) {

            Student student = (Student) context.getBean("student");
            System.out.println("Name  = " + student.getName());
            System.out.println("Grade = " + student.getGrade());
        }
    }
}

Here is the result of the code:

Name  = Alice
Grade = null

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I use PriorityBlockingQueue class?

This example demonstrate how to use the PriorityBlockingQueue class. The PriorityBlockingQueue is one implementation of the BlockingQueue interface. It is an unbounded concurrent queue. The object place in this type of queue must implement the java.lang.Comparable interface. The Comparable interface defines how the order priority of the elements inside this queue.

For simplicity, in this example we use strings object as the elements to be placed in the queue. The String class implements the comparable interface. Running this example will print out the names in the string array in alphabetical orders.

package org.kodejava.util.concurrent;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

public class PriorityBlockingQueueExample {
    public static void main(String[] args) {
        final String[] names =
                {"carol", "alice", "malory", "bob", "alex", "jacobs"};

        final BlockingQueue<String> queue = new PriorityBlockingQueue<>();

        new Thread(() -> {
            for (String name : names) {
                try {
                    queue.put(name);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Producer").start();

        new Thread(() -> {
            try {
                for (int i = 0; i < names.length; i++) {
                    System.out.println(queue.take());
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "Consumer").start();
    }
}

This code print out:

alex
alice
bob
carol
jacobs
malory

How do I inject beans, properties and methods using Spring EL?

Using Spring Expression Language (SpEL) we can inject object references or values into a bean dynamically when the bean is created instead of statically defined at development time. In this example you’ll learn how to inject a bean’s property using a property of another bean.

Let start by create two classes, the Student and Grade classes. The student object will have a property to store their grade name which will be obtained from the grade object.

package org.kodejava.spring.core.el;

public class Student {
    private String name;
    private String grade;

    public Student() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGrade() {
        return grade;
    }

    public void setGrade(String grade) {
        this.grade = grade;
    }
}
package org.kodejava.spring.core.el;

public class Grade {
    private String name;
    private String description;

    public Grade() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

Next we create the spring configuration file. In this configuration we have two beans definition, the grade and student bean. We set the name and description property of the grade bean.

We also set the name property of student bean using a string literal. But the grade property value is set to the grade‘s bean name property using the Spring EL, #{grade.name}. The expression tells the spring container to look for a bean whose id is grade, read its name and assign it to student‘s grade.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="grade" class="org.kodejava.spring.core.el.Grade">
        <property name="name" value="Beginner" />
        <property name="description" value="A beginner grade." />
    </bean>
    <bean id="student" class="org.kodejava.spring.core.el.Student">
        <property name="name" value="Alice" />
        <property name="grade" value="#{grade.name}" />
    </bean>

</beans>

And then create the following program to execute the spring container and retrieve the student bean from it.

package org.kodejava.spring.core.el;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpELDemo {
    public static void main(String[] args) {
        try (ClassPathXmlApplicationContext context =
                     new ClassPathXmlApplicationContext("spel-example.xml")) {

            Student student = (Student) context.getBean("student");
            System.out.println("Name  = " + student.getName());
            System.out.println("Grade = " + student.getGrade());
        }
    }
}

This program will print the following output:

Name  = Alice
Grade = Beginner

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I use LinkedBlockingQueue class?

In the following code snippet you will learn how to use the LinkedBlockingQueue class. This class implements the BlockingQueue interface. We can create a bounded queue by specifying the queue capacity at the object construction. If we do not define the capacity, the upper bound is limited to the size of Integer.MAX_VALUE.

The data in the queue represented as a linked node in a FIFO (First-In-First-Out) order. The head element of the queue is the longest element placed in the queue and the tail element is the latest element added to the queue.

Let’s see the code in action below:

package org.kodejava.util.concurrent;

import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class LinkedBlockingQueueExample {
    public static void main(String[] args) {
        final BlockingQueue<String> queue = new LinkedBlockingQueue<>(1024);

        // Producer Tread
        new Thread(() -> {
            while (true) {
                try {
                    String data = UUID.randomUUID().toString();
                    System.out.printf("[%s] PUT [%s].%n",
                            Thread.currentThread().getName(), data);
                    queue.put(data);
                    Thread.sleep(250);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Producer").start();

        // Consumer-1 Thread
        new Thread(() -> {
            while (true) {
                try {
                    String data = queue.take();
                    System.out.printf("[%s] GET [%s].%n",
                            Thread.currentThread().getName(), data);
                    Thread.sleep(550);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Consumer-1").start();

        // Consumer-2 Thread
        new Thread(() -> {
            while (true) {
                try {
                    String data = queue.take();
                    System.out.printf("[%s] GET [%s].%n",
                            Thread.currentThread().getName(), data);
                    Thread.sleep(750);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Consumer-2").start();
    }
}

The output of the code snippet above:

[Producer] PUT [34418601-19cf-41fc-aecc-a0fa7caa72bb].
[Consumer-1] GET [34418601-19cf-41fc-aecc-a0fa7caa72bb].
[Producer] PUT [f2050eaa-c575-4faf-89e8-1ad0e3fbce0e].
[Consumer-2] GET [f2050eaa-c575-4faf-89e8-1ad0e3fbce0e].
[Producer] PUT [2f24985b-009b-44c3-9cec-7a066aa08ecf].
[Consumer-1] GET [2f24985b-009b-44c3-9cec-7a066aa08ecf].
[Producer] PUT [b4332823-c1a2-4587-bf5f-1f67407d6945].
[Consumer-2] GET [b4332823-c1a2-4587-bf5f-1f67407d6945].
[Producer] PUT [33edcd78-1b14-4913-afe2-7f44d76db50b].
[Consumer-1] GET [33edcd78-1b14-4913-afe2-7f44d76db50b].

How to implement queue using the DelayQueue?

The java.util.concurrent.DelayQueue class in an implementation of the BlockingQueue interface. Elements added to the queue must implement the java.util.concurrent.Delayed interface.

The queue is unbound in size, enabling adds to return immediately, we can only take an element from the queue when the delay time has expired. If multiple elements have expired delays, the element with the longest delay expiration will be taken first.

package org.kodejava.util.concurrent;

import java.util.Random;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;

public class DelayQueueExample {
    public static void main(String[] args) {
        // Creates an instance of blocking queue using the DelayQueue.
        final BlockingQueue<DelayObject> queue = new DelayQueue<>();
        final Random random = new Random();

        new Thread(() -> {
            while (true) {
                try {
                    // Put some Delayed object into the Queue.
                    int delay = random.nextInt(10000);
                    DelayObject object = new DelayObject(
                            UUID.randomUUID().toString(), delay);

                    System.out.printf("Put object = %s%n", object);
                    queue.put(object);
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Producer Thread").start();

        new Thread(() -> {
            while (true) {
                try {
                    // Take elements out from the DelayQueue object.
                    DelayObject object = queue.take();
                    System.out.printf("[%s] - Take object = %s%n",
                            Thread.currentThread().getName(), object);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Consumer Thread-1").start();

        new Thread(() -> {
            while (true) {
                try {
                    // Take elements out from the DelayQueue object.
                    DelayObject object = queue.take();
                    System.out.printf("[%s] - Take object = %s%n",
                            Thread.currentThread().getName(), object);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Consumer Thread-2").start();
    }
}

Below is an implementation of the Delayed interface. In the implementation class we have to implement the getDelay(TimeUnit) and the compareTo(Object) methods.

package org.kodejava.util.concurrent;

import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayObject implements Delayed {
    private final String data;
    private final long startTime;

    public DelayObject(String data, long delay) {
        this.data = data;
        this.startTime = System.currentTimeMillis() + delay;
    }

    @Override
    public long getDelay(TimeUnit unit) {
        long diff = startTime - System.currentTimeMillis();
        return unit.convert(diff, TimeUnit.MILLISECONDS);
    }

    @Override
    public int compareTo(Delayed o) {
        return Long.compare(this.startTime, ((DelayObject) o).startTime);
    }

    @Override
    public String toString() {
        return "{" +
                "data='" + data + '\'' +
                ", startTime=" + startTime +
                '}';
    }
}

Running this example give you some kind of the following output:

Put object = {data='ff217d8f-30c7-4ff6-b107-f5e6b13b5cf1', startTime=1635830327667}
Put object = {data='ad9b7f64-04f6-45ba-8b4a-6d9d25785303', startTime=1635830326742}
Put object = {data='7e439219-486a-473f-b093-2ada26b682f4', startTime=1635830328540}
Put object = {data='1fd6f3d2-60b1-4986-a8d0-ceb0863b30a7', startTime=1635830328498}
[Consumer Thread-1] - Take object = {data='ad9b7f64-04f6-45ba-8b4a-6d9d25785303', startTime=1635830326742}
Put object = {data='9d8811a2-5f2a-487b-a229-11ad8ed54515', startTime=1635830330952}
Put object = {data='baf72a83-0242-42cb-93db-9ef08da5f78d', startTime=1635830336088}
[Consumer Thread-2] - Take object = {data='ff217d8f-30c7-4ff6-b107-f5e6b13b5cf1', startTime=1635830327667}
Put object = {data='9d4d14c5-0777-4675-aa67-a49a0519d9b2', startTime=1635830328952}
Put object = {data='c4979d10-4a11-44a8-b79c-ff31309e968b', startTime=1635830331430}