What is the keyword to use when the access of a method has to be restricted to only one thread at a time select one volatile synchronized final private?

Singleton is one of the most widely used creational design pattern to restrict the object created by applications. If you are using it in a multi-threaded environment, then the thread-safety of the singleton class is very important. In real-world applications, resources like Database connections or Enterprise Information Systems (EIS) are limited and should be used wisely to avoid any resource crunch. To achieve this, we can implement a Singleton design pattern. We can create a wrapper class for the resource and limit the number of objects created at runtime to one.

Thread Safe Singleton in Java

What is the keyword to use when the access of a method has to be restricted to only one thread at a time select one volatile synchronized final private?
In general, we follow the below steps to create a singleton class:

  1. Create the private constructor to avoid any new object creation with new operator.
  2. Declare a private static instance of the same class.
  3. Provide a public static method that will return the singleton class instance variable. If the variable is not initialized then initialize it or else simply return the instance variable.

Using the above steps I have created a singleton class that looks like below. ASingleton.java

package com.journaldev.designpatterns; public class ASingleton { private static ASingleton instance = null; private ASingleton() { } public static ASingleton getInstance() { if (instance == null) { instance = new ASingleton(); } return instance; } }

In the above code, the getInstance() method is not thread-safe. Multiple threads can access it at the same time. For the first few threads when the instance variable is not initialized, multiple threads can enter the if loop and create multiple instances. It will break our singleton implementation.

How to achieve thread-safety in Singleton Class?

There are three ways through which we can achieve thread safety.

  1. Create the instance variable at the time of class loading. Pros:
  • Thread safety without synchronization
  • Easy to implement

Cons:

  • Early creation of resource that might not be used in the application.
  • The client application can’t pass any argument, so we can’t reuse it. For example, having a generic singleton class for database connection where client application supplies database server properties.
  1. Synchronize the getInstance() method. Pros:
  • Thread safety is guaranteed.
  • Client application can pass parameters
  • Lazy initialization achieved

Cons:

  • Slow performance because of locking overhead.
  • Unnecessary synchronization that is not required once the instance variable is initialized.
  1. Use synchronized block inside the if loop and volatile variable Pros:
  • Thread safety is guaranteed
  • Client application can pass arguments
  • Lazy initialization achieved
  • Synchronization overhead is minimal and applicable only for first few threads when the variable is null.

Cons:

Looking at all the three ways to achieve thread-safety, I think the third one is the best option. In that case, the modified class will look like this:

package com.journaldev.designpatterns; public class ASingleton { private static volatile ASingleton instance; private static Object mutex = new Object(); private ASingleton() { } public static ASingleton getInstance() { ASingleton result = instance; if (result == null) { synchronized (mutex) { result = instance; if (result == null) instance = result = new ASingleton(); } } return result; } }

The local variable result seems unnecessary. But, it’s there to improve the performance of our code. In cases where the instance is already initialized (most of the time), the volatile field is only accessed once (due to “return result;” instead of “return instance;”). This can improve the method’s overall performance by as much as 25 percent. If you think there are better ways to achieve this or if the thread-safety is compromised in the above implementation, please comment and share it with all of us.

Bonus Tip

String is not a very good candidate to be used with synchronized keyword. It’s because they are stored in a string pool and we don’t want to lock a string that might be getting used by another piece of code. So I am using an Object variable. Learn more about synchronization and thread safety in java.

You can checkout more Java examples from our GitHub Repository.

Modifiers are keywords that let us fine-tune access to our class and its members, their scope, and behavior in certain situations. For example, we can control which classes/objects can access certain members of our class, whether a class can be inherited or not, whether we can override a method later, whether we should override a method later, etc.

Modifier keywords are written before the variable/method/class (return) type and name, e.g. private int myVar or public String toString().

Modifiers in Java fall into one of two groups - access and non-access:

native is not covered in more detail below since is a simple keyword that marks a method that will be implemented in other languages, not in Java. It works together with the Java Native Interface (JNI). It's used when we want to write performance critical sections of code in more performance-friendly languages (like C).

Want to learn more about access modifiers, as opposed to non-access? If so, check out our article Access Modifiers in Java.

Non-Access Modifiers

These types of modifiers are used to control a variety of things, such as inheritance capabilities, whether all objects of our class share the same member value or have their own values of those members, whether a method can be overridden in a subclass, etc.

A brief overview of these modifiers can be found in the following table:

Modifier Name Overview
static The member belongs to the class, not to objects of that class.
final Variable values can't be changed once assigned, methods can't be overriden, classes can't be inherited.
abstract If applied to a method - has to be implemented in a subclass, if applied to a class - contains abstract methods
synchronized Controls thread access to a block/method.
volatile The variable value is always read from the main memory, not from a specific thread's memory.
transient The member is skipped when serializing an object.

The static Modifier

The static modifier makes a class member independent of any object of that class. There are a few features to keep in mind here:

  • Variables declared static are shared among all objects of a class (since the variable essentially belongs to the class itself in this case), i.e. objects don't have their own values for that variable, instead, they all share a single one.
  • Variables and methods declared static can be accessed via the class name (instead of the usual object reference, e.g. MyClass.staticMethod() or MyClass.staticVariable), and they can be accessed without the class being instantiated.
  • static methods can only use static variables and call other static methods, and cannot refer to this or super in any way (an object instance might not even exist when we call a static method, so this wouldn't make sense).

Note: It's very important to note that static variables and methods can't access non-static (instance) variables and methods. On the other hand, non-static variables and methods can access static variables and methods.

This is logical, as static members exist even without an object of that class, whereas instance members exist only after a class has been instantiated.

Static Variables

For variables, we use static if we want the variable to be common/shared for all objects.

Let's take a look at how static variables behave differently from regular instance variables:

class StaticExample { public static int staticInt = 0; public int normalInt = 0; public StaticExample() { staticInt++; normalInt++; } } System.out.println(StaticExample.staticInt); StaticExample object1 = new StaticExample(); System.out.println(object1.staticInt); System.out.println(object1.normalInt); StaticExample object2 = new StaticExample(); System.out.println(object2.staticInt); System.out.println(object2.normalInt); object1.staticInt = 10; object1.normalInt = 10; System.out.println(object2.staticInt); System.out.println(object2.normalInt);

Static Methods

The most common example of using static is the main() method, it is declared as static because it must be called before any objects exist. Another common example is the Math class since we use the methods of that class without making an instance of it first (like Math.abs()).

A good way to think about static methods is "Does it make sense to use this method without first creating an object of this class?" (e.g. you don't need to instantiate the Math class in order to calculate the absolute value of a number).

Static methods can be used to access and modify static members of a class. Though, they're commonly used to manipulate method parameters or compute something and return a value.

These methods are referred to as utility methods:

static int average(int num1, int num2) { return (num1+num2)/2; }

This utility method can be used to calculate the average of two numbers, for an example.

As mentioned above, the Math class is often used for calling static methods. If we look at the source code, we can notice that it mostly offers utility methods:

public static int abs(int i) { return (i < 0) ? -i : i; } public static int min(int a, int b) { return (a < b) ? a : b; } public static int max(int a, int b) { return (a > b) ? a : b; }

Static Blocks

There's also a static block. A static block gets executed only once when the class is first instantiated (or a static member has been called, even if the class isn't instantiated), and before the rest of the code.

Let's add a static block to our StaticExample class:

class StaticExample() { ... static { System.out.println("Static block"); } ... } StaticExample object1 = new StaticExample(); StaticExample object2 = new StaticExample();

Irrespective of their position in the class, static blocks are initialized before any other non-static blocks, including constructors:

class StaticExample() { public StaticExample() { System.out.println("Hello from the constructor!"); } static { System.out.println("Hello from a static block!"); } }

Instantiating this class would output:

Hello from a static block! Hello from the constructor!

If multiple static blocks are present, they will run in their respective order:

public class StaticExample { static { System.out.println("Hello from the static block! 1"); } public StaticExample() { System.out.println("Hello from the constructor!"); } static { System.out.println("Hello from the static block! 2"); } }

Instantiating this class would output:

Hello from the static block! 1 Hello from the static block! 2 Hello from the constructor!

Static Imports

As already mentioned, it's better to call static members prefixed with the class name, rather than the instance name. Also, in some cases, we never really instantiate a class with static methods, such as the Math class, which offers numerous utility methods regarding maths.

That being said, if we use a class' static members often, we can import individual members or all of them using a static import. This allows us to skip prefixing their calls with the class name:

package packageOne; public class ClassOne { static public int i; static public int j; static public void hello() { System.out.println("Hello World!"); } } package packageTwo; static import packageOne.ClassOne.i; public class ClassTwo { public ClassTwo() { i = 20; } }

Or, if we'd like to import all static members of ClassOne, we could do it like so:

package packageTwo; import static packageOne.ClassOne.*; public class ClassTwo { public ClassTwo() { i = 20; j = 10; } }

The same applies to methods:

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

package packageTwo; import static packageOne.ClassOne.*; public class ClassTwo { public ClassTwo() { hello(); } }

Running this would output:

Hello World!

This may not seem that important, but it helps when we call many static members of a class:

public int someFormula(int num1, int num2, int num3) { return Math.ceil(Math.max(Math.abs(num1), Math.abs(num2))+Math.max(Math.abs(num2), Math.abs(num3)))/(Math.min(Math.abs(num1), Math.abs(num2))+Math.min(Math.abs(num2), Math.abs(num3))); } import static java.lang.Math.*; public int someFormula(int num1, int num2, int num3) { return ceil(max(abs(num1), abs(num2))+max(abs(num2), abs(num3)))/(min(abs(num1), abs(num2))+min(abs(num2), abs(num3))); }

The final Modifier

The keyword final can have one of three meanings:

  • to define named constants (variables whose values can't change after initialization)
  • to prevent a method from being overridden
  • to prevent a class from being inherited

Named Constants

Adding the final modifier to a variable declaration makes that variable unchangeable once it's initialized.

The final modifier is often used together with the static modifier if we're defining constants. If we only apply static to a variable, it can still be changed easily. There's also a naming convention tied to this:

static final double GRAVITATIONAL_ACCELERATION = 9.81;

Variables such as these are often included in utility classes, such as the Math class, accompanied by numerous utility methods.

Though, in some cases, they also warrant their own classes, such as Constants.java:

public static final float LEARNING_RATE = 0.3f; public static final float MOMENTUM = 0.6f; public static final int ITERATIONS = 10000;

Note: when using final with object reference variables, be careful of what type of behavior you expect. Consider the following:

class MyClass { int a; int b; public MyClass() { a = 2; b = 3; } } final MyClass object1 = new MyClass(); MyClass object2 = new MyClass();

The reference variable object1 is indeed final and it's value can't change, but what does that mean for reference variables anyway? It means that object1 can't change which object it is pointing to anymore, but we can change the object itself. This is something that often confuses people:

object1.a = 5;

Method parameters can also be declared final. This is used to make sure our method doesn't change the parameter it receives when it's called.

Local variables can also be declared final. This is used to make sure the variable receives a value only once.

Preventing Overriding

If you specify the final modifier while defining a method, any future subclass can't override it.

class FinalExample { final void printSomething() { System.out.println("Something"); } } class ExtendsFinalExample extends FinalExample { void printSomething(String something) { System.out.println(something); } }

One small bonus of declaring truly final methods as final is a slight performance boost whenever we call this method. Usually, Java resolves method calls dynamically at run-time, but with methods declared final, Java can resolve a call to it at compile time, or if a method is really small it can simply inline calls to that method since it "knows" that it won't be overridden. This eliminates the overhead associated with a method call.

Preventing Inheritance

This usage of final is fairly straight-forward, a class defined with final cannot be inherited. This of course implicitly declares all methods of that class final as well (they can't be overridden if the class can't be inherited in the first place).

final class FinalExample {...}

The abstract Modifier

The abstract modifier is used to define methods that will be implemented in a subclass later on. Most often it's used to suggest that some functionality should be implemented in a subclass, or (for some reason) it can't be implemented in the superclass. If a class contains an abstract method, it must also be declared abstract.

Note: You can not create an object of an abstract class. In order to do that, you need to provide an implementation for all the abstract methods.

An example would be if we had a simple class called Employee that encapsulates data and methods for an employee. Let's say that not every employee is paid in the same way, some types of employees are paid by the hour and some are paid a fixed salary.

abstract class Employee { int totalHours; int perHour; int fixedRate; ... abstract int salary(); ... } class Contractor extends Employee { ... int salary() { return totalHours*perHour; } ... } class FullTimeEmployee extends Employee { ... int salary() { return fixedRate; } ... } class Intern extends Employee { ... int salary() { return 0; } ... }

If a subclass doesn't provide an implementation to all abstract methods in the superclass, it has to be declared as abstract as well, and an object of that class can't be created.

Note: abstract is used heavily with polymorphism, e.g. we'd say ArrayList<Employee> employees = new ArrayList();, and add Contractor, FullTimeEmployee, and Intern objects to it. Even though we can't create an object of the Employee class, we can still use it as a reference variable type.

The synchronized Modifier

When two or more threads need to use the same resource, we somehow need to make sure that only one of them has access to it at a time, i.e. we need to synchronize them.

This can be achieved in several ways, and one simple and readable way (albeit with somewhat limited usage) is by using the synchronized keyword.

An important concept to understand before you see how to use this keyword is the concept of a monitor. Every object in Java has its own implicit monitor associated with it. A monitor is a "mutually exclusive" lock, meaning that only one thread can "own" a monitor at a time. When a thread enters the monitor, no other thread can enter it until the first thread exits. This is what synchronized does.

Threads are beyond the scope of this article so I will focus on the syntax of synchronized only.

We can synchronize access to methods, and blocks of code. Synchronizing blocks of code works by providing an object instance that we want to synchronize access to and the code that we want to perform related to that object.

class SynchronizedExample { ... SomeClass object = new SomeClass(); .... synchronized(object) { } synchronized void doSomething() { ... } ... }

The volatile Modifier

The volatile modifier tells Java that a variable can be changed unexpectedly by some other part of the program (like in multithreaded programming), and so that variable's value is always read from main memory (and not from CPU cache), and that every change to the volatile variable is stored in main memory (and not in CPU cache). With this in mind, volatile should only be used when necessary, since reading/writing to memory every time is more expensive than doing so with CPU cache and only reading/writing to memory when necessary.

In simplified terms - when a thread reads a volatile variable value, it is guaranteed that it will read the most recently written value. Basically, a volatile variable does the same thing that synchronized methods/blocks do, we just can't declare a variable as synchronized.

The transient Modifier

When a variable is declared as transient, that means that its value isn't saved when the object is stored in memory.
transient int a; means that when we write the object to memory, the contents of "a" will not be included. For example, it's used to make sure that we don't store private/confidential information in a file.

When we try to read an object that contains transient variables, all transient variable values will be set to null (or default values for primitive types), no matter what they were when we wrote the object to the file. Another example of usage would be when a variable's value should be derived based on other data (such as someone's current age), and isn't part of the persistent object state.

Note: Something very interesting happens when we use transient and final together. If we have a transient final variable that is evaluated as a constant expression (Strings or primitive types) the JVM will always serialize it, ignoring any potential transient modifier. When transient final is used with reference variables, we get the expected, default behavior of transient.

Conclusion

Modifiers are keywords that let us fine-tune access to our class and its members, their scope and behavior in certain situations. They provide fundamental traits for our classes and their members. Every developer should be thoroughly be acquainted with them to make the best use of them.

Like being aware that protected access control can easily be bypassed, or the transient final modifier when it comes to constant expressions.