What is thread?
A
thread is a lightweight sub-process. It is a separate path of execution. It is
called separate path of execution because each thread runs in a separate stack
frame
Multithreading
is a process of executing multiple threads simultaneously. Its main advantage
is:
- Threads share the
same address space.
- Thread is
lightweight.
- Cost of communication between process is low.
When
we create a Thread in java program, it’s known as user thread. A daemon thread
runs in background and doesn’t prevent JVM from terminating. When there are no
user threads running, JVM shutdown the program and quits. A child thread
created from daemon thread is also a daemon thread.
What is the difference between preemptive scheduling and time
slicing?
Under
preemptive scheduling, the highest priority task executes until it enters the
waiting or dead states or a higher priority task comes into existence. Under
time slicing, a task executes for a predefined slice of time and then re-enters
the pool of ready tasks. The scheduler then determines which task should
execute next, based on priority and other factors.
How can we create a Thread in Java?
There
are two ways to create Thread in Java – first by implementing Runnable
interface and then creating a Thread object from it and second is to extend the
Thread Class
What states can a thread have and what is the meaning of each state?
- NEW: A
thread that has not yet started is in this state.
- RUNNABLE: A
thread executing in the Java virtual machine is in this state.
- BLOCKED: A
thread that is blocked waiting for a monitor lock is in this state.
- WAITING: A
thread that is waiting indefinitely for another thread to perform a
particular action is in this state.
- TIMED_WAITING: A
thread that is waiting for another thread to perform an action for up to a
specified waiting time is in this state.
- TERMINATED: A
thread that has exited is in this state.
How do we set the priority of a thread?
The
priority of a thread is set by using the method setPriority(int). To set
the priority to the maximum value, we use the
constant Thread.MAX_PRIORITY and to set it to the minimum value we
use the constant Thread.MIN_PRIORITY because these values can differ
between different JVM implementations.
What do you understand about Thread Priority?
Every
thread has a priority, usually higher priority thread gets precedence in
execution but it depends on Thread Scheduler implementation that is OS
dependent. We can specify the priority of thread but it doesn’t guarantee that
higher priority thread will get executed before lower priority thread. Thread
priority is an int whose value varies from 1 to 10 where 1 is
the lowest priority thread and 10 is the highest priority thread.
How do we stop a thread in Java?
To
stop a thread one can use a volatile reference pointing to the current thread
that can be set to null by other threads to indicate the current thread should
stop its execution.
Is it possible to start a thread twice?
No,
after having started a thread by invoking its start() method, a
second invocation ofstart() will throw
an IllegalThreadStateException.
Can we call run() method of a Thread class?
Yes,
we can call run() method of a Thread class but then it will behave like a normal
method. To actually execute it in a Thread, we need to start it using Thread.start() method.
What is Thread Scheduler and Time Slicing?
Thread
Scheduler is the Operating System service that allocates the CPU time to the
available runnable threads. Once we create and start a thread, it’s execution
depends on the implementation of Thread Scheduler. Time Slicing is the process
to divide the available CPU time to the available runnable threads. Allocation
of CPU time to threads can be based on thread priority or the thread waiting
for longer time will get more priority in getting CPU time. Thread scheduling
can’t be controlled by java, so it’s always better to control it from
application itself.
What is the difference between yield() and sleep()?
yield()
method pauses the currently executing thread temporarily for giving a chance to
the remaining waiting threads of the same priority to execute. If there is no
waiting thread or all the waiting threads have a lower priority then the same
thread will continue its execution. The yielded thread when it will get the
chance for execution is decided by the thread scheduler whose behavior is
vendor dependent. If doesn't release the lock on the objects acquired.
sleep() allows the thread to go to sleep state for x milliseconds. When a thread goes into sleep state it doesn’t releases the lock.
sleep() allows the thread to go to sleep state for x milliseconds. When a thread goes into sleep state it doesn’t releases the lock.
What is the difference between wait() and sleep()?
- wait() is a method
of Object class. sleep() is a method of Object class.
- sleep() allows the thread to go to sleep state for x milliseconds. When a thread goes into sleep state it doesn’t release the lock. wait() allows thread to release the lock and goes to suspended state. The thread is only active when a notify() or notifAll() method is called for the same object.
What is difference between notify() and notfiyAll()?
notify()
wakes up the first thread that called wait() on the same object.
notifyAll() wakes up all the threads that called wait() on the same object. The highest priority thread will run first.
notifyAll() wakes up all the threads that called wait() on the same object. The highest priority thread will run first.
Why thread communication methods wait(), notify() and notifyAll()
are in Object class?
In
Java every Object has a monitor and wait, notify methods are used to wait for
the Object monitor or to notify other threads that Object monitor is free now.
There is no monitor on threads in java and synchronization can be used with any
Object, that’s why it’s part of Object class so that every class in java has
these essential methods for inter thread communication.
Why wait(), notify() and notifyAll() methods have to be called from
synchronized method or block?
When
a Thread calls wait() on any Object, it must have the monitor on the Object
that it will leave and goes in wait state until any other thread call notify()
on this Object. Similarly when a thread calls notify() on any Object, it leaves
the monitor on the Object and other waiting threads can get the monitor on the
Object. Since all these methods require Thread to have the Object monitor, that
can be achieved only by synchronization, they need to be called from
synchronized method or block.
What is a shutdown hook?
A
shutdown hook is a thread that gets executed when the JVM shuts down. It can be
registered by invoking addShutdownHook(Runnable) on the Runtime
instance:
Runtime.getRuntime().addShutdownHook(new
Thread() {
@Override
public void run() {
}
});
How can we achieve thread safety in Java?
There
are several ways to achieve thread safety in java – synchronization, atomic
concurrent classes, implementing concurrent Lock interface, using volatile
keyword, using immutable classes and Thread safe classes.
What is volatile keyword in Java
When
we use volatile keyword with a variable, all the threads read its value
directly from the memory and don’t cache it. This makes sure that the value
read is the same as in the memory.
Which is more preferred – Synchronized method or Synchronized block?
Synchronized
block is more preferred way because it doesn’t lock the Object, synchronized
methods lock the Object and if there are multiple synchronization blocks in the
class, even though they are not related, it will stop them from execution and
put them in wait state to get the lock on Object.
What is ThreadLocal?
Java
ThreadLocal is used to create thread-local variables. We know that all threads
of an Object share it’s variables, so if the variable is not thread safe, we
can use synchronization but if we want to avoid synchronization, we can use
ThreadLocal variables.
Every thread has it’s own ThreadLocal variable and they can use it’s get() and set() methods to get the default value or change its value local to Thread. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread.
Every thread has it’s own ThreadLocal variable and they can use it’s get() and set() methods to get the default value or change its value local to Thread. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread.
What is the purpose of thread groups?
Each
thread belongs to a group of threads. The JDK class java.lang.ThreadGroup provides
some methods to handle a whole group of Threads. With these methods we can, for
example, interrupt all threads of a group or set their maximum priority.
Thread
dump is list of all the threads active in the JVM, thread dumps are very
helpful in analysing bottlenecks in the application and analysing deadlock
situations. There are many ways using which we can generate Thread dump – Using
Profiler, Kill -3 command, jstack tool etc. I prefer jstack tool to generate
thread dump of a program because it’s easy to use and comes with JDK
installation. Since it’s a terminal based tool, we can create script to
generate thread dump at regular intervals to analyse it later on.
What is Deadlock? How to analyze and avoid deadlock situation?
Deadlock
is a programming situation where two or more threads are blocked forever, this
situation arises with at least two threads and two or more resources.
To
analyze a deadlock, we need to look at the java thread dump of the application,
we need to look out for the threads with state as BLOCKED and then the
resources it’s waiting to lock, every resource has a unique ID using which we
can find which thread is already holding the lock on the object.
Avoid
Nested Locks, Lock Only What is Required and Avoid waiting indefinitely are
common ways to avoid deadlock situation,
What is a livelock?
A
livelock is a situation in which two or
more threads block each other by responding to an action that is caused by
another thread. In contrast to a deadlock situation, where two or more threads
wait in one specific state, the threads that participate in a livelock change
their state in a way that prevents progress on their regular work. An example
would be a situation in which two threads try to acquire two locks, but release
a lock they have acquired when they cannot acquire the second lock. It may now
happen that both threads concurrently try to acquire the first thread. As only
one thread succeeds, the second thread may succeed in acquiring the second
lock. Now both threads hold two different locks, but as both want to have both
locks, they release their lock and try again from the beginning. This situation
may now happen again and again.
Threads
with lower priority get less time for execution than threads with higher
priority. When the threads with lower priority performs a long enduring
computations, it may happen that these threads do not get enough time to finish
their computations just in time. They seem to “starve” away as threads with
higher priority steal them their computation time.
The
order in which threads can enter a synchronized block is not defined. So in
theory it may happen that in case many threads are waiting for the entrance to
a synchronized block, some threads have to wait longer than other threads.
Hence they do not get enough computation time to finish their work in time.
A
race condition describes constellations in which the outcome of some
multi-threaded implementation depends on the exact timing behavior of the
participating threads. In most cases it is not desirable to have such a kind of
behavior, hence the term race condition also means that a bug due to missing
thread synchronization leads to the differing outcome. A simple example for a
race condition is the incrementation of an integer variable by two concurrent
threads. As the operation consists of more than one single and atomic
operation, it may happen that both threads read and increment the same value.
After this concurrent incrementation the amount of the integer variable is not
increased by two but only by one.
A
fair lock takes the waiting time of the threads into account when choosing the
next thread that passes the barrier to some exclusive resource. An example
implementation of a fair lock is provided by the Java
SDK: java.util.concurrent.locks.ReentrantLock. If the constructor with the
boolean flag set to true is used, the ReentrantLock grants access to the
longest-waiting thread.
Is it possible to check whether a thread holds a monitor lock on
some given object?
The
class java.lang.Thread provides the static
method Thread.holdsLock(Object) that returns true if and only if the
current thread holds the lock on the object given as argument to the method
invocation.
java.util.Timer
is a utility class that can be used to schedule a thread to be executed at
certain time in future. Java Timer class can be used to schedule a task to be
run one-time or to be run at regular intervals.
java.util.TimerTask
is an abstract class that
implements Runnable interface and we need to extend this class to create our
own TimerTask that can be scheduled using java Timer class.
What is Thread Pool? How can we create Thread Pool in Java?
A
thread pool manages the pool of worker threads, it contains a queue that keeps
tasks waiting to get executed.
A
thread pool manages the collection of Runnable threads and worker threads execute
Runnable from the queue.
java.util.concurrent.Executors
provide implementation of java.util.concurrent.Executor interface to create the
thread pool in java..
What is the purpose of the class java.lang.ThreadLocal?
As
memory is shared between different threads, ThreadLocal provides a
way to store and retrieve values for each thread separately. Implementations
of ThreadLocal store and retrieve the values for each thread
independently such that when thread A stores the value A1 and thread B stores
the value B1 in the same instance of ThreadLocal, thread A later on
retrieves value A1 from this ThreadLocal instance and thread B
retrieves value B1.
What do we understand by lock contention?
Lock
contention occurs, when two or more threads are competing in the acquisition of
a lock. The scheduler has to decide whether it lets the thread, which has to
wait sleeping and performs a context switch to let another thread occupy the
CPU, or if letting the waiting thread busy-waiting is more efficient. Both ways
introduce idle time to the inferior thread.
In
some cases, lock contention can be reduced by applying one of the following
techniques:
- The scope of the
lock is reduced.
- The number of times
a certain lock is acquired is reduced (lock splitting).
- Using hardware
supported optimistic locking operations instead of synchronization.
- Avoid
synchronization where possible.
- Avoid object
pooling.
How do you solve producer consumer problem in Java?
There are basically two ways to solve
this problem in Java, one by using wait
and notify method and other by using Blocking
Queue Java. later is easy to implement and a good choice if you
are coding in Java 5.
No comments:
Post a Comment