Multi Threading Java Interview Questions – Set 09

Why is locking of a method or block of code for thread safety is called “synchronized” and not “lock” or “locked

When a method or block of code is locked with the reserved “synchronized” key word in Java, the memory (i.e. heap) where the shared data is kept is synchronized.

This means,When a synchronized block or method is entered after the lock has been acquired by a thread, it first reads any changes to the locked object from the main heap memory to ensure that the thread that has the lock has the current info before start executing.

After the synchronized  block has completed and the thread is ready to relinquish the lock, all the changes that were made to the object that was locked is written or flushed back to the main heap memory so that the other threads that acquire the lock next has the current info.

This is why it is called “synchronized” and not “locked”. This is also the reason why the immutable objects are inherently thread-safe and does not require any synchronization. Once created, the immutable objects cannot be modified.

Explain different way of using thread

A Java thread could be implemented by using Runnable interface or by extending the Thread class. The Runnable is more advantageous, when you are going for multiple inheritance.

What is the difference between processes and threads

A process is an execution of a program but a thread is a single execution sequence within the process. A process can contain multiple threads. A thread is sometimes called a lightweight process.

A JVM runs in a single process and threads in a JVM share the heap belonging to that process. That is why several threads may access the same object. Threads share the heap and have their own stack space. This is how one thread’s invocation of a method and its local variables are kept thread safe from other threads. But the heap is not thread-safe and must be synchronized for thread safety.

How will you take thread dump in Java? How will you analyze Thread dump

A Thread Dump is a complete list of active threads. A java thread dump is a way of finding out what each thread in the JVM is doing at a particular point of time. This is especially useful when your java application seems to have some performance issues. Thread dump will help you to find out which thread is causing this. There are several ways to take thread dumps from a JVM. It is highly recommended to take more than 1 thread dump and analyze the results based on it. Follow below steps to take thread dump of a java process

  • Step 1

On UNIX, Linux and Mac OSX Environment run below command:

ps -el | grep java

On Windows:

Press Ctrl+Shift+Esc to open the task manager and find the PID of the java

process

  • Step 2:

Use jstack command to print the Java stack traces for a given Java process PID

jstack [PID]

Can a thread call a non-synchronized instance method of an Object when a synchronized method is being executed

Yes, a Non synchronized method can always be called without any problem. In fact Java does not do any check for a non-synchronized method. The Lock object check is performed only for synchronized methods/blocks. In case the method is not declared synchronized Jave will call even if you are playing with shared data. So you have to be careful while doing such thing. The decision of declaring a method as synchronized has to be based on critical section access. If your method does not access a critical section (shared resource or data structure) it need not be declared synchronized. Below is the example which demonstrates this, The Common class has two methods synchronizedMethod1() and method1() MyThread class is calling both the methods in separate threads,

public class Common {

public synchronized void synchronizedMethod1() {

System.out.println(“synchronizedMethod1 called”);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(“synchronizedMethod1 done”);

}

public void method1() {

System.out.println(“Method 1 called”);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(“Method 1 done”);

}

}

public class MyThread extends Thread {

private int id = 0;

private Common common;

public MyThread(String name, int no, Common object) {

super(name);

common = object;

id = no;

}

public void run() {

System.out.println(“Running Thread” + this.getName());

try {

if (id == 0) {

common.synchronizedMethod1();

} else {

common.method1();

}

} catch (Exception e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

Common c = new Common();

MyThread t1 = new MyThread(“MyThread-1”, 0, c);

MyThread t2 = new MyThread(“MyThread-2”, 1, c);

t1.start();

t2.start();

}

}  

Here is the output of the program

Running ThreadMyThread-1

synchronizedMethod1 called

Running ThreadMyThread-2

Method 1 called

synchronizedMethod1 done

Method 1 done

This shows that method1() – is called even though the synchronizedMethod1() was in execution.

What is the difference between Thread.start() & Thread.run() method

Thread.start() method (native method) of Thread class actually does the job of running the Thread.run() method in a thread. If we directly call Thread.run() method it will executed in same thread, so does not solve the purpose of creating a new thread.

Can you have a true singleton class in Java? How would you write a thread-safe singleton class

A singleton class is something for which only one instance exists per class loader. Single instance for a wholeapplication cannot be guaranteed. That is just definition of what is singleton.

The one that is  popular with the interviewers is writing a thread-safe singleton class.

For example, the following singleton class is not thread-safe because before a thread creates the Singleton instance, another thread can proceed to the instantiation part of the code

— instance = new Object( );

to create more than one instance of the Singleton object.

Even though the code

–> instance = new Object( );

appears to be single line, the JVM has to execute a number of internal steps like allocating memory, creating a new object and assigning the newly created object to the referenced variable.

Only after the completion of these steps,the condition instance == null will return false.

//          final so that cannot be subclassed

public final class Singleton {

private static Object instance = null;

//private so that it cannot be instantiated from outside this class

private Singleton() {}

public static Object getInstance() {

if (instance == null) {

instance = new Object();

}

return instance;

}

}

So, we can make the above code thread-safe in a number of ways.

Option 1: Synchronize the whole method or the block of code. This approach is not efficient as the use of synchronized keyword in a singleton class means that only one thread will be executing the synchronized block at a time and all other threads would be waiting.

Option 2: Eagerly initialize the singleton instance when the class is actually loaded as opposed to initializing it lazily at at run time only when it is accessed.

//final so that cannot be subclassed

public final class ThreadSafeSingleton {

//eager initialization and instantitiated as soon as the class is loaded by a classloader in the JVM

private static Object instance = new Object();

//private so that it cannot be instantiated from outside this class

private Singleton() {}

public static Object getInstance() {

return instance;

}

}

Option 3: You can use the “Initialize-On-Demand Holder Class” idiom proposed by Brian Goetz to create a thread-safe lazy-initialized Singleton as shown below by creating an inner class.

public final class ThreadSafeSingleton {

//      private so that it cannot be instantiated from outside this class

private ThreadSafeSingleton() {}

//      static inner class, invoked only when ThreadSafeSingleton.getInstance() is called

private static class ThreadSafeSingletonHolder {

private static ThreadSafeSingleton instance = new ThreadSafeSingleton();

}

public static Object getInstance() {

return ThreadSafeSingletonHolder.instance;

}

}

Option 4: is to create a per thread singleton as discussed earlier with the ThreadLocal class for the SimpledateFormat.

How does thread synchronization occurs inside a monitor? What levels of synchronization can you apply?What is the difference between synchronized method and synchronized block

  • In Java programming, each object has a lock. A thread can acquire the lock for an object by using the synchronized keyword.
  • The synchronized keyword can be applied in method level (coarse grained lock – can affect performance adversely) or block level of code (fine grained lock).
  • Often using a lock on a method level is too coarse. Why lock up a piece of code that does not access any shared resources by locking up an entire method.
  • Since each object has a lock, dummy objects can be created to implement block level synchronization.
  • The block level is more efficient because it does not lock the whole method.
  • The JVM uses locks in conjunction with monitors.
  • A monitor is basically a guardian who watches over a sequence of synchronized code and making sure only one thread at a time executes a synchronized piece of code.
  • Each monitor is associated with an object reference.
  • When a thread arrives at the first instruction in a block of code it must obtain a lock on the referenced object.
  • The thread is not allowed to execute the code until it obtains the lock.
  • Once it has obtained the lock, the thread enters the block of protected code.
  • When the thread leaves the block, no matter how it leaves the block, it releases the lock on the associated object. For static methods, you acquire a class level lock.

Explain how you would get a Thread Deadlock with a code example

The example below causesa deadlocksituation bythread-1 waiting for lock2and thread-0 waiting for lock1.

 

package deadlock;

public class DeadlockTest extends Thread

{

public static Object lock1 = new Object();

public static Object lock2 = new Object();

public void method1()

{

synchronized (lock1)

{

delay(500);  //some operation

System.out.println(“method1: ” + Thread.currentThread().getName());

synchronized (lock2)

{

System.out.println(“method1 is executing …. “);

}

}

}

public void method2()

{

synchronized (lock2)

{

delay(500);   //some operation

System.out.println(“method1: ” + Thread.currentThread().getName());

synchronized (lock1)

{

System.out.println(“method2 is executing …. “);

}

}

}

public void run()

{

method1();

method2();

}

public static void main(String[] args)

{

DeadlockTest thread1 = new DeadlockTest();

DeadlockTest thread2 = new DeadlockTest();

thread1.start();

thread2.start();

}

private</span> void delay(long timeInMillis)

{

try

{

Thread.sleep(timeInMillis);

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

}

The output will be something like:

method1: Thread-0

method1 is executing ….

method2: Thread-0

method1: Thread-1

—deadlock —– can’t proceed further

Why do we need run() & start() method both. Can we achieve it with only run method

We need run() & start() method both because JVM needs to create a separate thread which can not be differentiated from a normal method call. So this job is done by start method native implementation which has to be explicitly called. Another advantage of having these two methods is we can have any object run as a thread if it implements Runnable interface. This is to avoid Java’s multiple inheritance problems which will make it difficult to inherit another class with Thread.