Java Threads

JVM Threads:
1. Main Thread
2. Memory Management Thread
3. System Management

Benefits of Threads:
1. Threads are lightweight compared to processes, it takes less time and resource to create a thread.
2. Threads share their parent process data and code.
3. Context switching between threads is usually less expensive than between processes.
4. Thread intercommunication is relatively easy than process communication.

What is the difference between Thread and daemon Thread?

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. It has low priority. 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.

How do we create Thread in Java?
1. Implementing the java.lang.Runnable interface and creating a thread object with it.
2. Extend the java.lang.Thread class., if you extend Thread class you cannot extend any other class.

When to extend Thread instead of Runnable?

We should never extend Thread, in fact Thread class should be final, it’s a design flaw.
Usually some people override Thread class to override getId(), but we should not do that as all the concurrency package use native thread ID which will be different and can cause arbitrary behaviour. Also, if we override Thread class, then the object will be of type Thread.
One instance of extending thread is to get singleton instance of some background daemon tasks like GC, shutdown, CPU Monitor, Catalina Shutdown Hook,

MongoCursorCleaner, Auditing – Auditing can be a producer-consumer use case where all threading are producing audit events and pushing them to a queue and the audit thread is consuming those events from the queue, so create AuditEventThread by extending thread class, create a singleton instance and start the thread by calling its start method , the same behaviour however can be achieved by implementing the runnable interface as well.

Another important point to note is whenever a thread execution is exiting, it will call notifyAll() on its object so that any thread waiting for its lock will be notified, this is how join() is implemented. join() waits on the lock of the thread and once the thread execution is over, the waiting thread will be notified. Now imagine, the thread object is also used as a lock in some piece of the code, now this lock will get false notification due to thread exit and hence it is very bad idea to extend Thread.

What is context-switching in multi-threading?
Context-Switching is the process of storing and restoring of CPU state so that Thread execution can be resumed from the same point at a later point of time. Context Switching is the essential feature for multitasking operating system and support for multi-threaded environment.

Why threads 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’s monitor or to notify other threads that object’s 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.
Threads do not know status of other threads or which other thread is waiting for that lock.
Java is based on Hoare’s monitors idea. In Java all objects has a monitor.

Threads waits on monitors so, to perform a wait, we need 2 parameters:
– A Thread
– A monitor( any Object)

In the Java design, the thread can not be specified, it is always the current thread running the code. However, we can specify the monitor (which is the object we can wait on). This is a good design, because if we could make any other thread to wait on a desired monitor, this would lead to an “intrusion”, posing difficulties on designing/programming concurrent programs. Remember that in Java all operations that are intrusive in another thread’s execution are deprecated (e.g. stop() )

What is the major advantage of new Lock interface?
Provide two separate lock for reading and writing.

Why Thread sleep() and yield() methods are static?
Thread sleep() and yield() methods work on the currently executing thread. So there is no point in invoking these methods on some other threads that are in wait state, that’s why these methods are made static so that when this method is called statically, it works on the currently executing thread and avoid confusion to the programmers who might think that they can invoke these methods on some non-running threads.

Why Should I NOT call sleep()/yield method on any other Thread?
Because it is error prone and can cause deadlock, if one thread asks another thread to go to sleep, it wont release the lock and if the thread which is going to resume it needs the lock held by sleeping thread then there is a dead lock (not really, sleep do not sleep indefinitely like suspend and do not need notification to wake up ). Same reason with Suspend.?

Why wait(), notify() and notifyAll() must be called from synchronized block or method in Java ?
To avoid race condition, if T1 has checked on some condition and decided to wait, context-switch happens and T2 satisfies the condition and issues notify() which is unheard by T1 since it is not yet waiting, hence T1 will miss this notification and will still go in wait(). In short, before waiting lock must be acquired so that no one else should be able to notify before it starts waiting and hence it wont miss the notification signal.

How can we achieve thread safety in Java?
1. Synchronization
2. Atomic Classes
3. Immutable Classes
4. Lock Interface
5. Volatile
6. Thread safe classes


Why is Thread.stop() deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behaviour can result. This behaviour may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.

Couldn’t I just catch the ThreadDeath exception and fix the damaged object?

Complicate writing correct multithreaded code:
1. A thread can throw a ThreadDeath exception almost anywhere. All synchronized methods and blocks would have to be studied in great detail, with this in mind.
2. A thread can throw a second ThreadDeath exception while cleaning up from the first (in the catch or finally clause). Cleanup would have to be repeated till it succeeded. The code to ensure this would be quite complex.

Why are Thread.suspend and Thread.resume deprecated?
Thread.suspend is deadlock prone. If a thread is suspending while in critical section it holds the monitor and no other thread can enter the critical section unless the previous thread is resumed, and if the thread which will resume the previous wants the same monitor than a deadlock occurs, such condition is known as “frozen” state. Use wait and notify instead.

What about Thread.destroy?
It is similar to Thread.suspend without resume.

What happens when exception occurs in Thread?
If not caught thread will die, if an uncaught exception handler is registered then it will get a callback. JVM will query the thread for its uncaughtexception handler using Thread.getUnCaughtExceptionHandler() and will invoke the handler’s uncaughtException(), passing thread and the exception as arguments

What is FutureTask?
Cancellable asynchronous computation in Java application. This class provides a base implementation of Future. Start and cancel a computation, query to see if the computation is complete and get the result of the computation. get() will block till the result is available.
Executor Service takes a callable task and returns Future.


Runnable {
    
public abstract void run();

}

Callable {
    
V call() throws Exception;

}

Future {
    
isCancelled();
    
cancel()
;
    isDone()
;
    get()
;
}


RunnableFuture extends Runnable,
Future
FutureTask implements RunnableFuture
FutureTask implements Future interface and gives us way to start and cancel the task.
It is better for the ExecutorService to create the FutureTask instead of we wrapping Callable in FutureTask and providing it to the ExecutorService since there will be multiple references in the later case.

Difference between interrupted() and isInterrupted()?
Former clears the interrupt status while the later does not.
Thread.interrupt() sets this flag.
status is cleared after IE is thrown.

Difference between livelock and deadlock in Java?
Livelock is a special case of resource starvation. A thread acts in response of other thread and other thread’s action is also response of another thread then livelock may result. However, the threads are not blocked, they are simply too busy to respond to each other to resume work.

How to check if a thread holds lock on a particular object in Java?
1. Invoke object.wait(), will throw IllegalMonitorStateException if Thread does not hold lock of that object.
2. Thread.holdsLock(Object obj) will return if current thread holds lock of object.

Difference between Reentrant and Synchronized?
1. Reentrant has tryLock along with timeout, synchronized is indefinite block
2. Reentrant supports fairness
3. interrupt Thread while waiting for reentrant lock.
4. Gets list of all waiting thread on reentrant lock.

Difference between volatile and atomic?
Volatile guarantees happens-before that a write will happen before any subsequent write.
atomic variables provide option to perform compound operation atomically.

Difference between CountDownLatch and CyclicBarrier?
CountDownLatch can not be reused once it reaches zero. Good for onetime event like startup.
CyclicBarrier can be reused by calling its reset(). Recurring event like calculating solution of big problem. Another example is multi player game, wait for all players to join.

public class CyclicBarrierExample {
    private static class Task implements Runnable {
        CyclicBarrier barrier;
        Task(CyclicBarrier barrier) {
            this.barrier = barrier;
         }

        @Override
        public void run() {
              try {
                  System.out.println("Waiting for barrier to breach");
                  barrier.await();
                  System.out.println("Thread"+Thread.currentThread().getId()+", has crossed barrier" );
               }
              catch(BrokenBarrierException bbe){
                  bbe.printStackTrace();
              }
        }
     }


    public static void main( String [] args ) {
        final CyclicBarrier cb = new CyclicBarrier(3, new Runnable() {
              @Override
              public void run(){
                  System.out.println("All parties arrived at the barrier, lets play");
              }
         });
         Thread t1 = new Thread(new Task(cb));
         Thread t2 = new Thread(new Task(cb));
         Thread t3 = new Thread(new Task(cb));
         t1.start();
         t2.start();
         t3.start();
    }
}

If another Thread calls reset() on barrier, all awaiting threads will terminate and throw BrokenBarrierException.
Important points about CyclicBarrier:
1. CyclicBarrier can perform completion task once all thread reaches to barrier, this can be specified while creating barrier.
2. If CyclicBarrier is created with 3, means 3 threads need to call await() method to break the barrier.
3. Thread will block on await() until all parties reaches to barrier, another thread interrupt or await timeout.

Why String is immutable?
1. Cache hashcode value and can be used in HashMap
2. Security issue, accessing any file by changing name or loading class. Used as parameters in many Java classes.
3. Can be shared safely between threads.
4. String pool.

What happens if thread throws an exception inside synchronized block?
Thread will relinquish lock no matter what, this wont happen in lock interface, hence lock.unlock should always be in finally block.

Multithreading best practices?
1. Give meaningful name to threads
.
2. Avoid locking or scope of synchronization.
3. Prefer concurrent collections over synchronized
.
4. Always release lock lock.unlock() in finally block
.
5. Prefer synchronizers over wait and notify
Fork-join
work-stealing algorithm, uses multiprocessor capabilities.

What is Semaphore in Java?

What is Mutex?

Difference between Mutex and Semaphore?
1. Mutex is essentially the same thing as a binary semaphore.
2. Mutex has owner, semaphore does not.
3. Mutex supports priority inversion since it knows its owner, can increase its priority.
4. Mutex provides deletion safety. Owner of mutex cannot be deleted.

Difference between Mutex and Monitor?
Scope, mutex is at system, monitor is at application level.

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.

private static final ThreadLocal localString = new ThreadLocal() {
    @Override
    protected String initialValue() {
            return "Hello World - ThreadLocal" ;
    }
};

What is Thread Group?
1. Used in ThreadPool while creating new threads.
2. List of active threads in a group.
3. Set unCaughtExceptionHandler.
4. Can interrupt the TG.
5. Custom way of creating new threads – with specific name.

Reference:
https://docs.oracle.com/javase/8/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html