Interview Questions – Thread
Java Synchronization
Every object can be used as a limiting
resource or monitor object, and to constrain access to code in a critical
section.
[Implementation - Each object has header
represented by two 32-bit words - Lock word and Class word. In Lock word (which
also contains GC state information), it carries synchronization information,
such as whether the object is used in a lock right now.]
How synchronization is implemented?
Synchronization is implemented using
monitors. Each object's header is associated with a monitor, which a thread can
lock or unlock.
Only one thread at a time may hold a lock
on a monitor. Any other threads attempting to lock that monitor are
blockeduntil they can obtain a lock on that monitor.
The synchronized statement computes a
reference to an object; it then attempts to perform a lock action on that
object's monitor and does not proceed further until the lock action has
successfully completed. After the lock action has been performed, the body
of the synchronized statement is executed.
If execution of the body is ever
completed, either normally or abruptly, an unlock action is automatically
performed on that same monitor.
Class lock vs Object lock
A synchronized method acquires a monitor
before it executes. For a class (static) method, the monitor associated with
the Class object for the method's class is used. For an instance method, the
monitor associated with this (the object for which the method was invoked) is
used.
Synchronizing an instance method uses the
object's lock, since we assume we're modifying the state of a specific object -
and each object is separate from every other of the same class. If a class has
two instance synchronized methods, then it is possible to access each of these
synchronized methods by two different objects simultaneously. If the
synchronized method is a static method, a class lock is used (since the method
is assumed to act the same for all instances).
If 2 different threads hit 2 different
synchronized methods in an object at the same time will they both
continue?
No. Only one method can acquire the lock. 2
different threads can not access instance synchronized method on same object
simultaneously. 2 different threads can access instance synchronized method on
2 different objects simultaneously. Because of Class lock, 2 different threads
can NOT access static synchronized method on 2 different objects
simultaneously. If a
thread goes to sleep, it holds any locks it has—it doesn't release them. If a
class has both synchronized and non-synchronized methods, multiple threads can
still access the class same object's synchronized method and non-synchronized
method simultaneously.
One point you have to be careful about is
that there is no link between synchronized static methods and synchronized non
static methods
class A { static synchronized f() {...}
synchronized g() {...} } f() and g() are not synchronized with each other and
thus can execute totally concurrently.
On an instance method, to implement mutual
exclusion between different instances of the object - for example when accessing
an external resource):
g() {synchronized(MyClass.class) {}}
Explain ways of creating a thread, what is
the difference? Which is better?
There are two ways to create a new thread:
First, Extends the Thread class, and override the run() method in your class.
In order to start a new thread, we need initialize an instance of the subclass
and invoke the start() method on it. Second, Implements the Runnable interface,
The class will have to implement the run() method in the Runnable interface. In
order to start a new thread, we need create an instance of this class. Pass the
reference of this instance to the Thread constructor a new thread of execution
will be created. Implementing the runnable interface is preferred, as it does
not require your object to inherit a thread. When you need multiple
inheritance, for example, if you are already inheriting a different class, then
only interfaces can help you.
How can threads communicate with each other
in java?
The wait(), notify(), and notifyAll()
methods are used to provide an efficient way for threads to communicate with
each other.
What is the difference between yield() and
sleep()?
When a task invokes yield(), it changes
from running state to runnable state. It allows the current the thread to
release its lock from the object and scheduler gives the lock of the object to
the other thread with same priority. When a task invokes sleep(), it changes
from running state to waiting/sleeping state. It allows the thread to go to
sleep state for the specified milliseconds. When a thread goes into sleep state
it doesn't release the lock.
What is difference between notify() and
notfiyAll()?
When notify is called, one of the threads
waiting for the synchronized resource will be arbitrarily selected and woken up
by the thread scheduler in the JVM.
When notifyAll is called, all threads
waiting for the lock will be woken up. Only one of them will succeed in
acquiring the lock and the rest will go to sleep again.
The notifyAll method is safer than notify
but carries a greater overhead than notify.
What is daemon thread and which method is
used to create the daemon thread?
Threads are divided into two types: normal
threads and daemon threads. When a new thread is created, it inherits the
daemon status of the thread that created it, so by default any threads created
by the main thread are also normal threads. Normal threads and daemon threads
differ only in what happens when they exit. Daemon threads are sometimes called
"service" threads. These are threads that normally run at a low
priority and provide a basic and helper service to a program. You don't want
the existence of this thread to prevent the JVM from shutting down. This is
what daemon threads are for. An example of a daemon thread that is continuously
running is the garbage collector thread. This thread is provided by the JVM.
When a thread exits, the JVM performs an inventory of running threads, and if
the only threads that are left are daemon threads, it initiates an orderly
shutdown. When the JVM halts, any remaining daemon threads are abandoned,
finally blocks are not executed, stacks are not unwound the JVM just exits.
The setDaemon() method is used to create a
daemon thread. These threads run without the intervention of the user.
Is there a separate stack for each thread in
Java?
Yes. Every thread maintains its own
separate stack, called Runtime Stack but they share the same memory. Elements
of the stack are the method invocations, called activation records or stack
frame. The activation record contains pertinent information about a method like
local variables.
What is synchronization?
With respect to multithreading,
Synchronization is a process of controlling the access of shared resources by
the multiple threads in such a manner that only one thread can access a
particular resource at a time. In non synchronized multithreaded application,
it is possible for one thread to modify a shared object while another thread is
in the process of using or updating the object’s value. Synchronization
prevents such type of data corruption which may otherwise lead to dirty reads
and significant errors.
What is synchronization advantage and
disadvantage?
Without synchronization, it is possible
for one thread to modify a shared object while another thread is in the process
of using or updating that object’s value. This often causes dirty data and
leads to significant errors. The disadvantage of synchronization is that it can
cause deadlocks when two threads are waiting on each other to do something.
Also synchronized code has the overhead of acquiring lock, which can adversely
the performance.
Resources: