Translate

Wednesday, July 3, 2013

Threading

Q1. Does a simple Java program made of only one thread.
Ans. No. There are many threads involved even in a simple Java program as listed below:
1. Thread for translating bytecodes to machine instructions.
2. A low priority thread for Garbage collector.
3. A thread for main method.
4. If your application handles input, a separate thread to handle input from mouse and keyboard and many more threads could exist depending upon your program.

However, first 3 threads exist for each application.


Q2. Threading types/ways 
Ans.
1. Preemptive – Scheduling mechanism provides time slice for each thread, forcing a thread to give up control after certain time.

2. Cooperative – Each task voluntarily gives up control, thus reducing the context switching overhead. However, programmer needs to be very careful.

Q3. How to implement threads.
Ans.
a.) Extending Thread (class)
b.) Implementing Runnable (Interface)

c.) Implementing Callable

When a class is derived from Runnable, it must have a run() method, but that doesn't produce any innate threading abilities. To achieve threading behavior, you must explicitly attach a task to a thread as given below:

new Thread ( new Test() );
    where Test implements Runnable interface.


Q4.Compare Runnable and Callable.
Ans:
Runnable: A separate task that performs work, but it doesn't return a value.
Callable: Similar to Runnable, except that a callable object can return a result or throw a checked exception. Also, it has call() method in place of run().


Q5. How does run() method of Thread terminates. 
Ans.
1. By returning from run() method. 
2. Executing last statement in method body, i.e completing the task.
3. main() thread terminates. 

4. Throws an exception or fails to catch an exception.  
NOTE: It can’t throw a CHECKED exception.

Q6. What is the default implementation of Thread/Runnable run() method. 
Ans. Thread class' run() method does nothing, so sub-classes should override the method with code to execute in the second thread. If a Thread is instantiated with a Runnable argument, the thread's run() method executes the run() method of the Runnable object in the new thread instead.

Q7. Difference between start() and run() methods
Ans. start() methods only schedules the thread for execution and not actually begins the execution of the thread. The start method creates a new thread which calls the run method. The execution of the thread is started when the JVM calls the run() method of the thread, once the CPU Scheduler picks this scheduled thread for execution.

If the run() method of two threads invoked separately, they will execute one after the other. Thus, calling the run method won't actually give you multi-threading. If the start() method is used on two threads, both threads runs simultaneously. The start() method invokes the run() method asynchronously, where as the run() methods run synchronously.

Conclusion: the start() method call run() method asynchronously (does not wait for any result, just fire up an action), while we run run() method synchronously - we wait when it quits and only then we can run the next line of our code.


Q8. Can I implement my own start() method? 
Ans. Thread start() method is not marked final, but should not be overridden. This method contains the code that creates a new executable thread and is very specialized. Your threaded application should either pass a Runnable type to a new Thread, or extend Thread and override the run() method.

Q9. Can a constructor be called by multiple threads. 
Ans. No, constructor would never be called by multiple threads. However, a constructor can’t be synchronized though you can use synchronized block inside constructor. Using the synchronized keyword with a constructor is a syntax error. This is because only the thread that creates an object should have access to it while it is being constructed and hence any other thread is not granted access until the construction of the object is complete. So, no explicit synchronization needed for constructors.

A constructor always gets a different this reference on each invocation. Constructors and hence any thread calling constructor always works on distinct objects. So no point of synchronization on constructors by java. If we pass some shared object to constructor,then we can use synchronized block on that shared object inside constructor.


Q10. Can I start a thread inside constructor?
Ans. Starting threads inside a constructor can be quite problematic, because another task might start executing before the constructor has completed, which means the task may be able to access the object in an unstable state.

Q11. Can I call start method more than once or can I start a thread more than once?
Ans. It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution. It throws IllegalThreadStateException if the thread was already started. 

Q12. What are different states of Thread.
Ans. A thread can be in any one of four states:
1.New/Initial: A thread remains in this state only momentarily, as it is being created. It allocates any necessary system resources and performs initialization. At this point it becomes eligible to receive CPU time. The scheduler will then transition this thread to the runnable or blocked state
.
2.Runnable: This means that a thread can be run when the time-slicing mechanism has CPU cycles available for the thread. Thus, the thread might or might not be running at any moment, but there’s nothing to prevent it from being run if the scheduler can arrange it. That is, it’s not dead or blocked.
3.Blocked: The thread can be run, but something prevents it. While a thread is in the blocked state, the scheduler will simply skip it and not give it any CPU time. Until a thread reenters the runnable state, it won’t perform any operations.
4.Dead: A thread in the dead or terminated state is no longer schedulable and will not receive any CPU time. Its task is completed, and it is no longer runnable. One way for a task to die is by returning from its run() method, but a task’s thread can also be interrupted.

Q13. How can a thread go into blocked state?
Ans.
1. You’ve put the task to sleep.
2. You’ve suspended the execution of the thread with wait(). It will not become runnable again until the thread gets the notify() or notifyAll() message (or the equivalent signal() or signalAll()).
3. Task is waiting for some I/O to complete.
4. Task is trying to call a synchronized method on another object, and lock is already acquired by someone else.

Q14. How to prevent deadlocks
Ans. Anytime that a task can be blocked in such a way that it cannot be interrupted, you have the potential to lock up a program. One of the features added in the Java SE5 concurrency 
libraries is the ability for tasks blocked on ReentrantLocks to be interrupted, unlike tasks blocked on synchronized methods or critical sections.

Q15. State the conditions for deadlock to occur.

Ans. Deadlock can occur if four conditions are simultaneously met:
1. Mutual exclusion: At least one resource used by the tasks must not be share-able.
2. Waiting for resource: At least one task must be holding a resource and waiting to acquire a resource currently held by another task.
3. Non-Preemptive: A resource cannot be preemptively taken away from a task. Tasks only release resources as a normal event.
4.Circular wait: A circular wait can happen, whereby a task waits on a resource held by another task, which in turn is waiting on a resource held by another task, and so on, until one of the tasks is waiting on a resource held by the first task, thus grid locking everything.


Q16. Explain livelock? 
Ans. A thread often acts in response to the action of another thread. If the other thread's action is also a response to the action of another thread, then livelock may result. As with deadlock, livelocked threads are unable to make further progress. However, the threads are not blocked — they are simply too busy responding to each other to resume work. This is comparable to two people attempting to pass each other in a corridor: Alphonse moves to his left to let Gaston pass, while Gaston moves to his right to let Alphonse pass. Seeing that they are still blocking each other, Alphone moves to his right, while Gaston moves to his left. And this goes on.

Q17. What are the different ways to be thread safe?
Ans.
1. Local variables: Local primitive variables are thread-safe, because every thread has its own private set of local variables stored in a stack frame. Hence, local variables are never shared between threads.
2. Volatile keyword
3. Synchronization
4. Immutable Objects: Immutable objects, (ones without any setter methods, e.g. Integer) are automatically thread safe.
5. Parameters and Return values: Parameters and return values of primitive data types are always thread-safe because, as well as local variables, they are stored in each thread’s local stack. In this sample each calling thread will have its own copy of gear variable.


// A thread-safe method returning modified parameter
public int shiftTo(int gear)

{
      ++gear;
      return gear;
}

However, if we make use of instance/class variable and try to modify the same, its not thread safe.

6. Object References: Local object references are created in a thread’s stack frame and, therefore, are thread-safe. However, object instances that are being referenced by the local object references are created on a heap shared by all threads. Hence, as long as a particular object instance is accessible only by a single thread it is thread-safe. An object instance stops being thread-safe the moment it becomes exposed to a concurrent access by multiple threads.

7. Atomic classes: Ex Atomic Integer, AtomicLong and AtomicReference


Q18. What is daemon Thread.
Ans. Java has two types of threads: daemon and user.

A "daemon" thread is intended to provide a general service in the background as long as the program is running, but is not part of the essence of the program. Thus, when all of the non-daemon threads complete, the program is terminated, killing all daemon threads in the process. Conversely, if there are any non-daemon threads still running, the program doesn't terminate. There is, for instance, a non-daemon thread that runs main().

Ex:
Thread daemon = new Thread(new SimpleDaemons())
;
//Setting thread as daemon thread - Ensure to call this before start()
daemon.setDaemon(true);
daemon.start();

The setDaemon() method can be called only before the thread has been started. While the thread is running, you cannot cause a user thread to become a daemon thread (or vice versa); attempting to do so generates an exception. To be completely correct, an exception is generated any time the thread is alive and the setDaemon() method is called.

You can find out if a thread is a daemon by calling isDaemon().By default, a thread is a user thread if it is created by a user thread; it is a daemon thread if it is created by a daemon thread.


Q19. Does a thread goes through finally block?
Ans: You should be aware that daemon threads will terminate their run() methods without executing finally clauses, but non-daemon threads go through finally clause.

This is because, Daemons are terminated "abruptly" when the last of the non-daemons terminates. So as soon as main() exits, the JVM shuts down all the daemons immediately, without any of the formalities you might have come to expect. Since you cannot shut daemons down in a nice fashion, they are rarely a good idea.


Q20. Join in threads. 
Ans. The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing, t.join() causes the current thread to pause execution until t's thread terminates. Overloads of join allow the programmer to specify a waiting period. However, as with sleep, join is dependent on the OS for timing, so you should not assume that join will wait exactly as long as you specify.

Like sleep, join responds to an interrupt by exiting with an InterruptedException.

try
{
    t.join(5000); //current thread waits for thread “t” to complete but does not wait more than 5 sec
    if (t.isAlive())
    {
        //timeout occurred. Thread “t” has not finished 
    }
    else
    {
        //thread “t” has finished 
    }
}


Q21. What is the difference between yield and sleeping? 
Ans: When a task invokes yield(), it changes from running state to runnable state. This moves the CPU from one thread to other. With the yield method, the thread never goes into the sleeping state. It only allows other threads of the same priority to execute. Now if there are no threads of the same priority or any thread that could utilize the yielding of the currently running thread(say t1), then t1 may immediately come into running state. But if t1 is not in runnable state when yield() method is called then it cannot immediately come into running state from runnable state.

When a task invokes sleep(), it changes from running state to sleeping state. With sleep(), thread will be in sleeping state until the specified time, irrespective of anything.

NOTE: Both yield() and sleep() don't free lock and are static methods


Q22. Talk about sleep and wait methods. 
Ans.
Thread.sleep: Sends the current thread into non-runnable state for the specified amount of time. But, this doesn't cause the thread to loose ownership of the acquired monitors. So, if the current thread is into a synchronized block/method, then no other thread will be able to enter that block/method. This method throws InterruptedException if another thread interrupts it. This is a static method, so even if you try to call "t.sleep()" on a different thread, it’ll be called on the current thread only and not on the "t" thread. In fact, one should avoid calling any static method on an object reference. 

It has 2 variants
a.) sleep(long milliseconds): 
b.) sleep(long milliseconds, int nanoseconds): The second argument ‘int nanoseconds’ can acquire a value of the range 0-999999. IllegalArgumentException is thrown if either the value of milliseconds is negative or the value of nanoseconds is not in the range 0-999999.

Wait(): It is a method in Object class. This releases the lock prior to waiting (internally by Virtual machine itself) and reacquires the same before returning from wait.

NOTE: There is no concept of releasing and reacquiring locks in Java API’s. Thus, its not possible to implement wait() functionality in pure Java. Its a native method.

It is a method in Object class. It has 3 variants:
a.) public final void wait(long timeout)
b.) public final void wait(long timeout, int nanoseconds)
c.) public final void wait()


All the three methods throw InterruptedException & IllegalMonitorStateException. The first two may also throw IllegalArgumentException. The wait() method also sends the current thread into Non-Runnable state like the sleep() method.

Difference between the two is that unlike sleep(), wait() releases the locks before going into non-runnable state. Another apparent difference is that wait() is an instance method, while sleep() is a static method. The method wait() should be called for an object only when the current thread has already acquired lock for that object. This causes the current thread to wait either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed and after that the thread starts participating in thread scheduling process to acquire the monitor of the object to proceed further.

The method wait(1000), causes the current thread upto sleep up to one second. A thread could sleep less than 1 second if it receives the notify() or notifyAll() method call.

The call to sleep(1000) causes the current thread to sleep for exactly 1 second.

Q23. Hard wait and Soft wait.
Ans.
Hard wait: Waiting indefinitely.
Soft wait: Waiting till a time period

Q24. Why the methods wait(), notify() and notifyall() are in Object class rather than Thread class?
Ans. The reason behind this is that we generally use these methods in multi-threading scenario. The most simple and obvious reason is that any Object (not just a thread) can be the monitor for a thread. The wait() and notify() are called on the monitor i.e object and running thread just checks with the monitor. Every POJO which is involved in multi-threading may use synchronized methods or synchronized blocks for concurrent access and thus subsequently use wait(), notify(), notifyall() to release/inform about locks. I

The act of waiting is associated with the Object class because any subclass may need to wait for a ready state to occur. Wait mechanism expects that multiple threads may be waiting for the same object. The wait() and notify() methods are hosted by the Object class so that JVM can manage the “wait set” of threads through the objects they are waiting for. If these methods used in Thread class then we'll have to extend Thread class or implement Runnable Interface for every POJO. That would be not desirable. Because we don't want to make every object as thread.


A common example would be a limited pool or store of objects where you must wait for a storage slot to be released or an object to be returned to the pool before you can use it.

public synchronized Object getNextObject()
{
    // Waiting loop

    while (! objectAvailable())
    {
        try
        {
            wait();
        }
        catch (InterruptedException e)
        {
            // Handle exception
        }
}

// No longer waiting, get the return object
Object returnObject;

// Assign the returnObject from store and notify state change for other waiters
notify();
return returnObject;

Additionally, the communication among the interested threads becomes far too easier when the control is kept at the object's level - one common shared resource/medium and all interested threads communicating via it. If you'd try to accomplish this with wait() and notify() defined in the Thread class, you would HAVE to find out exactly which Thread was in wait() in order to call its notify() method to wake it up and make it resume processing. 

Q25. Preconditions for calling wait(), notify() or notifyAll().
Ans. The only place you can call wait(), notify(), or notifyAll() is within a synchronized method or block. However, sleep() can be called within synchronized and non-synchronized methods since it doesn’t manipulate the lock.

If you call any of these within a method that’s not synchronized, the program will compile, but when you run it, you’ll get an IllegalMonitorStateException with the somewhat non-intuitive message "current thread not owner." This message means that the task calling wait(), notify(), or notifyAll() must "own" (acquire) the lock for the object before it can call any of those methods.

To manipulates lock, you must first capture that object’s lock. For example, if you want to send notifyAll() to an object x, you must do so inside a synchronized block that acquires the lock for x.

synchronized(x)
{
      x.notifyAll();
}

Also, one should call wait() only after checking some condition so that you don’t miss out the signal to come out of wait(). For 
ex:

synchronized(sharedMonitor)
{
      while(someCondition)
            sharedMonitor.wait();
}

However, if it is changed to below:
while(someCondition) 
{      synchronized(sharedMonitor)
      {
            sharedMonitor.wait();
      }
}

Now here, context switching may occur after testing the condition, making the condition to false. But, you will go to wait() as you had tested the condition before and never able to come out of wait() as you have missed the signal.


Q26. Why do you need notifyAll() when only one thread will be executing at last.
Ans. With notify(), we can’t control which thread gets the notification. Its possible that thread getting notified is waiting on a different condition. By waking all threads, threads decide among themselves who should execute next.

Q27. Compare notify() and notifyAll()
Ans. Using notify() instead of notifyAll() is an optimization. Only one task of the possible many that are waiting on a lock will be awoken with notify(), so you must be certain that the right task will wake up if you try to use notify(). In addition, all tasks must be waiting on the same condition in order for you to use notify(), because if you have tasks that are waiting on different conditions, you don’t know if the right one will wake up. If you use notify(), only one task must benefit when the condition changes.

Also, with notifyAll(), only the tasks that are waiting on a particular lock are awoken i.e the lock which is going to be released with notifyAll() call. Remember, notifyAll() does NOT wakes up "all waiting tasks”. However, both will result in waking up a single thread waiting on the Object. notify() can be seen as an optimization of notifyAll(), which can only be used if there's a only one thread to proceed.

NOTE: With notify() and notifyall(), only thread(s) waiting on lock object that is going to be released are woken up and not the others (waiting on another object lock)


Q28. What happens when notify() is called and no thread is in waiting state.
Ans. Since wait() and notify() mechanism doesn’t know the condition for which its sending notification, notification() goes unheard if no thread is waiting.

Again, since condition is not known while sending notification(), developer should retest the condition after returning from wait(). This is required since another thread could have tested the condition and acquired the lock, before first thread received the notification, thus making the condition to false again. That’s the reason wait() method is always put in a loop.


Q29. Does order of statements play a role in creating a thread safe environment.
Ans. Yes, but you shouldn't strictly rely on statements order to be sure that your program is thread safe. This is because JVM may re-order few statements to provide an efficient execution.

1. However, volatile variables are not re-ordered like other statements. 
2. Similarly, statements inside synchronized block cannot be reordered to outside synchronized block. However, reverse is not true, i.e. statements outside synchronized block (before and after) can be re-ordered inside synchronized block. 

Q30. How to interrupt a thread and how to identify if a thread is interrupted?
Ans. The interrupt mechanism is implemented using an internal flag known as the interrupt status. On calling interrupt method on thread, its interrupt status is set. Thus, thread will throw an InterruptedException
a.) if it is already blocked i.e inside a blocking operation e.g sleep() or
b.) if it attempts a blocking operation after interrupt status is set (i.e after interrupt is called on thread)


To call interrupt(), you must hold a Thread object. If you call shutdownNow() on an Executor, it will send an interrupt() call to each of the threads it has started. However, there are times when you may want to only interrupt a single task. If you’re using Executors, you can hold on to the context of a task when you start it by calling submit() instead of execute(). submit() returns a generic Future<?>, with an unspecified parameter because you won’t ever call get() on it — the point of holding this kind of Future is that you can call cancel() on it and thus use it to interrupt a particular task. If you pass true to cancel(), the thread executing this task should be interrupted and otherwise, in-progress tasks are allowed to complete. Thus cancel() is a way to interrupt individual threads started with an Executor.

NOTE: sleep() is an example of interruptible blocking whereas I/O and waiting on a synchronized lock are not interruptible.

The interrupted status will be reset if
a.) Exception is thrown or
b.) Task calls static method Thread.interrupted().
Thus Thread.interrupted() provides another way to leave your run() loop, without throwing an exception. 

Q31. Difference between interrupted and isInterrupted
Ans. When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static Thread.isInterrupted, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag.

Clearing the interrupted status ensures that the framework will not notify you twice about a task being interrupted. You will be notified via either a single InterruptedException or a single successful Thread.interrupted() test. If you want to check again to see whether you were interrupted, you can store the result when you call Thread.interrupted().

Q32. List down conditions for an interrupt to occur.
Ans. Only time that the interrupt occurs is
1.) when the task enters a blocking operation
2.) or is already inside a blocking operation
     (except,in the case of uninterruptible I/O or synchronized methods)

If you've written code that may not make such a blocking call , but can only exit by throwing an exception on a blocking call, you won’t always be able to leave the run() loop. For ex: if you call interrupt() to stop a task, your task needs a second way to exit since your run() loop doesn't happen to be making any blocking calls. This opportunity is presented by the interrupted status, i.e invoking Thread.interrupted() which is set by the call to interrupt().


Q33. How to catch exceptions in Threads.
Ans. Because of the nature of threads, you can’t catch an exception that has escaped from a thread. Once an exception gets outside of a task’s run() method, it will propagate out to the console unless you take special steps to capture such errant exceptions. All uncaught exceptions are handled by code outside of the run() method before the thread terminates. 

Before Java SE5, you used thread groups to catch these exceptions. The default exception handler is the uncaughtException() method of ThreadGroup class. uncaughtException() method is automatically called when that thread is about to die from an uncaught exception. The thread is technically completed when the run() method returns, even though the exception handler is still running the thread. 

However, in Java SE5, Thread.UncaughtExceptionHandler is a new interface. It allows you to attach an exception handler to each Thread object. For ex:

         t.setUncaughtExceptionHandler(h);
where h is the Exception Handler class implementing Thread.UncaughtExceptionHandler interface and t is a thread object.  Then, any exception thrown by thread "t" is handled by Handler "h".

Q34. How to set default exception handler in threads.
Ans. If you know that you’re going to use the same exception handler everywhere, simpler approach is to set the default uncaught exception handler, which sets a static field inside the Thread class. For ex:


       Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
where MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler

This interface has handleException(), which the implementer overrides to take appropriate action. This handler is only called if there is no per-thread uncaught exception handler. The system checks for a per-thread version, and if it doesn't find one it checks to see if the thread group specializes its uncaughtException() method; if not, it calls the defaultUncaughtExceptionHandler

The static methods of the Thread class set or retrieve a default thread handler used by all new threads. When a thread is constructed, its exception handler is set to the default, so calling the setDefaultExceptionHandler() method does not affect any threads that have already been constructed.

NOTE: The exception handler for a particular thread can be set at any time, unlike default exception handler.


Q35. What is Thread local class and why would you need it
Ans. ThreadLocal is a convenience tool for creating thread specific variablesIt is a handy class for simplifying development of thread-safe concurrent programs by making the object stored in this class not sharable between threads. An instance of a ThreadLocal variable is created in an object. Enclosing object that is shared b/w the threads but ThreadLocal instance is not). ThreadLocal objects are usually stored as static fields. ThreadLocal class encapsulates non-thread-safe classes to be safely used in a multi-threaded environment and also allows you to create per-thread-singleton

To be more clear, let's take one simple example. If you have a class having some private/public static fields defined in it then all the objects created in all threads will share the same instances of those static fields. What if you want every thread to have a separate copy of it? ThreadLocal class will be of use in such cases, in fact they are mainly used for this purpose only. You can't just switch to a non-static field as in that case all the objects (even those created in the same thread) will have their own copies. You may come across situations asking you to have copies based on threads and not based on instances. This is where you will like to use ThreadLocal.

When you create a ThreadLocal object, you are only able to access the contents of the object using the get() and set() methods. This gives the developers an API to set/get attributes of a given thread object by simply giving them a single address field within the thread context variable, in which case every thread can have it's own pointer to a data structure that the developer wants to be thread specific.

Q36. What is a ThreadLocal (java.lang.ThreadLocal) class?
Ex:
public class SerialNum
{
      // The next serial number to be assigned
      private static int nextSerialNum = 0;
      private static ThreadLocal serialNum = new ThreadLocal()
      {
            protected synchronized Object initialValue()
            {
                  return new Integer(nextSerialNum++);
            }
      };

      public static int get()
      {
            return ( (Integer) serialNum.get()).intValue();
      }

      public static int set(int i)
      {
            serialNum.set(i);
      }
}

Being static, object (i.e serialNum here) is shared among threads. When get() method of ThreadLocal variable i.e. serialNum is called, internal mechanism returns the specific object assigned to specific thread.

The fact that you can only retrieve or modify the value of a thread local variable from a current thread is actually a shortcoming. There is absolutely nothing that prevents a user from specifying the thread, that should be used to retrieve or modify the value, but current implementation of ThreadLocal is locked into operating with value of Thread.currentThread(), so the visibility into ThreadLocal is limited to the thread you are currently running. Certainly, if the API allowed to specify the actual thread, it would be necessary to synchronize the access. Currently, there is no synchronization involved when using thread local variables, as it is always guaranteed that you are working with the thread object instance that you are currently running in.


Q37. Explain about methods in ThreadLocal class.
Ans. This class has only three methods
1. protected initialValue()
2.public get()
3.public set()


protected Object initialValue() - Returns the initial value of the ThreadLocal variable for the current thread and it's invoked at most once per thread. This method will be executed only when the thread calls the get() method for first time, given that thread doesn't call set() method prior to calling get() on it.

public Object get() - It will return the value of the ThreadLocal variable for the current thread.

public void set(Object value) - Like any other setter, this method will also set the current thread's copy of the ThreadLocal variable to the passed 'value'. This method is used only rarely as in most of the cases initialValue() method solves the purpose in a better way.

Q38. What is InheritableThreadLocal.
Ans. It is a subclass of ThreadLocal. Since, all threads have their own copy of ThreadLocal variable, they have their own states. If I want to use state of already existing thread, I need to use InheritableThreadLocal.

InheritableThreadLocal which subclasses ThreadLocal class is used in such situations. This class has only one method protected Object childValue(Object parentValue) which is used to set the initial value of the InheritableThreadLocal variable in the child thread. This method is called from within the parent thread before the child thread is created. Default implementation makes the child values identical to parent's, but we can override the childValue() method to set the child value as a function of the parent value
. By default, the childValue() returns the same input argument, but again an override of the childValue method might change this behavior as well.

When child thread calls the get() method, get() looks up the value associated with parent thread which then passes the same value to childValue() method for child value to be initialized. Thus, InheritableThreadLocal class allows a child thread to inherit the value of ThreadLocal variable from its parent.

Q39. Why is stop() method deprecated. 
Ans. stop() method works by throwing an Exception; which could have left the system in bad or erroneous state and we don’t want to proceed with that. To avoid such cases, it may be better to use explicit locks at the cost of increased program complexity.
ThreadDeath class is what caused the stop() method to become deprecated. Because it's thrown immediately upon receipt of the stop() method, it has the potential to leave shared data in an inconsistent state. And because it releases any locks on synchronized blocks or data that it holds, it has the potential to allow other threads to access the inconsistent data, even if that data is correctly synchronized.

Option would have been to catch the ThreadDeath exception and fix the damaged object, but it would vastly complicate the task of writing correct multi-threaded code. The task would be nearly insurmountable for two reasons:
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 repeated till it succeeded. The code to ensure this would be quite complex. In sum, it just isn't practical.

Replacement: Most uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. To ensure prompt communication of the stop-request, the variable must be volatile or access to the variable must be synchronized.

Q40. Why is resume() method deprecated.
Ans. Thread.suspend is inherently deadlock-prone. If the target thread holds a lock on the monitor protecting a critical system resource when it is suspended, no thread can access this resource until the target thread is resumed. If the thread that would resume the target thread attempts to lock this monitor prior to calling resume, deadlock results. Such deadlocks typically manifest themselves as "frozen" processes.

Replacement: Similar to Thread.stop(), the prudent approach is to have the "target thread" poll a variable indicating the desired state of the thread (active or suspended). When the desired state is suspended, the thread waits using Object.wait(). When the thread is resumed, the target thread is notified using Object.notify().

Q41. How to make thread safe singleton.
Ans.
1. Synchronize the getInstance() method.

2. Second approach to thread safety declares a constant Singleton attribute on the Singleton class itself:public class Singleton {
      public final static Singleton instance = new Singleton();
      private Singleton() {};

      public static void main( String [] args ) {
            Singleton instance = Singleton.instance;            // ...
      }
}
Variable “instance” will be initialized when the class loads. 

3. Third approach is to use synchronized block
public class ExampleSingleton {
      private static ExampleSingleton instance;

      public static ExampleSingleton getInstance() {

            // non-synchronized to prevent locking in case instance has already been created
            if ( instance == null ) {
                  synchronized( ExampleSingleton.class ) {

                        // Synchronized to prevent pre-emption and checking for is-nullable again
                        // to ensure that object is not created and not in stage of creation)
                        if ( instance == null ) { 
                             instance = new ExampleSingleton();
                        }
                  }//sync ends
            }
            return instance;
      }
}

Q42. Talk about thread scheduling
Ans. JVM is required to implement a preemptive, priority-based scheduler among its various threads. Each thread in a Java program is assigned a certain priority, a positive integer that falls within a well-defined range, which is set/changed by developer and never by JVM.

The priority value is important because the contract between the JVM and the underlying operating system is that the operating system must generally choose to run the Java thread with the highest priority. This OS scheduler is implemented in a preemptive fashion, meaning that when a higher-priority thread comes along, that thread interrupts (preempts) whatever lower-priority thread is running at the time. The contract with the operating system, however, is not absolute, which means that the operating system can sometimes choose to run a lower-priority thread.

Java's requirement for a priority-based, preemptive scheduling mechanism maps well to many operating systems like Solaris, Windows, Linux etc. Certain operating systems, particularly those on specialized devices and on smaller, handheld devices, do not provide that level of scheduling support; JVM implementations for those operating systems must perform the necessary thread scheduling on their own.


Q43. Talk about thread priorities
Ans. We can conceive that a thread scheduler keeps track of all the threads on which it operates by using linked lists; every thread is on a list that represents the state of the thread. A Java thread can have one of 11 priorities, so we conceive of 14 linked lists: one for all threads in the initial state, one for all threads in the blocked state, one for all threads in the exiting state, and one for each priority level. The list of threads at a given priority level represents only those threads that are currently in the runnable state: a thread in the runnable state at priority 7 is placed on the priority 7 list, but when the thread blocks, it moves to the blocked linked list. We're speaking here of having 11 priorities, but that number is a Java abstraction: an operating system may have more or fewer priorities than that.

For simplicity, we conceive of these threads as being on an ordered list; in reality, they may be held in simple pools. Keeping the threads in a linked list implies that threads will be selected to run in a particular order. While that is a useful way of thinking about the process, it is not necessarily the way an implementation may work.

In the Java Thread class, three static final variables define the allowable range of thread priorities:
1. Thread.MIN_PRIORITY: The minimum priority a thread can have 
when assigned by developer (although JVM is allowed to have lower-priority threads than this one), 
2. Thread.MAX_PRIORITY: The maximum priority a thread can be assigned by developer.
3. Thread.NORM_PRIORITY: The default priority for a thread
Minimum priority available to developers is 1, the maximum is 10, and the default is 5. This yields 10 distinct priorities that you can assign to a a thread; the 11th priority (priority 0) is reserved for the virtual machine.

Q44. Thread complex priorities.
Ans. Priority assigned to threads by OS could be different from priority assigned by JVM. We mentioned that Java has 11 priority levels (10 of which are available to developers), but this is an abstraction of the Java language. Operating systems usually have many more priorities. More important, though, is that the priority that the OS assigns to a thread is a complex formula that takes many pieces of information into account. A simple version of this formula might be this:
      RealPriority = JavaPriority + SecondsWaitingForCPU

Because of the way in which these values map to thread priorities of OS, threads with different Java priorities may end up with the same OS priority.

Complex priorities are advantageous because they help to prevent thread starvation. On the other hand, complex priorities mean that you cannot guarantee thread scheduling. In particular, you cannot use thread priorities to try and prevent race conditions in data access: a lower-priority thread can interrupt a higher-priority thread while it is in the process of updating shared data. You also cannot use thread priorities to ensure a certain order of execution between tasks.


Q45. Difference b/w pre-emption and time-slicing.
Ans. Preemption means only that a higher-priority thread runs instead of a lower-priority one, but when threads have the same priority, they do not preempt each other. With time-slicing, threads are allowed to run for a certain time, irrespective of priority.

Java does not mandate that its threads be time-sliced, but most operating systems do so.

Q46. What is Priority inversion
Ans. When a high-priority thread attempts to acquire a lock that is held by a lower-priority thread, it temporarily runs with an effective priority of the lower-priority thread.

Ex: Suppose that we have a thread with a priority of 8 that wants to acquire a lock that is held by a thread with a priority of 2. Because the priority 8 thread is waiting for the priority 2 thread to release the lock, it ends up running with an effective priority of 2. This is known as priority inversion.

Q47. 
What is Priority Inheritance
Ans. Priority inversion is often solved by priority inheritance. With priority inheritance, a thread that holds a lock that is wanted by a thread with a higher priority has its priority temporarily and silently raised - its new priority becomes the same as the priority of the thread that it is causing to block. When the thread releases the lock, its priority is lowered to its original value.

The goal of priority inheritance is to allow the high-priority thread to run as soon as possible. It is a common feature of OS and JVM’s running on those OS are subject to it. However, it is not a requirement of the Java specification.

Q48. What are Active Objects
Ans. One alternative approach for threading is called active objects or actors. This comes from the world of procedural programming. The reason the objects are called "active" is that each object maintains its own worker thread and message queue, and all requests to that object are enqueued, to be run one at a time. So with active objects, we serialize messages rather than methods, which means we no longer need to guard against problems that happen when a task is interrupted midway through its loop. When you send a message to an active object, that message is transformed into a task that goes on the object’s queue to be run at some later point. The Java SE5 Future comes in handy for implementing this scheme.


Q49. What is use of Thread Groups. Talk about it.
Ans. Every thread you create automatically belongs to a default thread group that JVM sets up on your behalf. Every thread we've looked at so far belongs to this existing thread group, which is known as the "main" thread group.

JVM also has a "system" thread group. This thread group contains the threads that handle finalization and weak references. This group does not contain all threads of JVM like garbage collection.

Thread groups are more than just arbitrary groupings of threads; they are related to each other. Every thread group has a parent thread group, so thread groups exist in a tree hierarchy. The obvious exception to this, of course, is the root of the tree, which is known as the root thread group or the system thread group.

Thread groups have two advantages:
1. Methods of the thread group class allow you to operate on all threads in the group.
Ex: If you wanted to interrupt all threads in a particular group, you could call the interrupt() method on the thread group object, and it would call the interrupt() method of each of its threads. The interrupt() method is really the only method of the ThreadGroup class that can affect all the threads in the group; stop(), suspend(), and resume() methods operate in the same way, but they are, of course, deprecated.

2. The second advantage of thread groups relates to thread security. If you write custom security code for your application, decisions about whether one thread can access and/or modify the state of another thread take into account the thread group to which the threads belong.

Q50. How do you maintain security with threads.
Ans. When certain operations are attempted on threads or thread groups, they use the internal method checkAccess() to confirmthe access.


Signature: void checkAccess(); Ex;
t.checkAccess() =>  Determines if the currently running thread has permission to modify t, where t could be a thread or thread group. And if there is a security manager, its checkAccess method is called with t as its argument.

Please note that return type is Void. checkAccess() method generates a Runtime exception if thread policy is violated by the operation. Assuming that no exception is thrown, an internal method is called that actually performs the logic of the method.

The checkAccess() method within the Thread and ThreadGroup classes is public, so you can call it directly from any thread or thread group object if you want to check what security policy is in place. Given method is final within the ThreadGroup class but can be overridden in Thread class allowing you to change the security model for your particular Thread class. Remember, however, that this would affect only your class and not other threads within the system.

Q51. SecurityManager's checkAccess() method
Ans. checkAccess method in SecurityManager class handles security policies for the Thread and ThreadGroup class. When the checkAccess() method of security manager is called, the security manager consults the thread group of the calling thread - it is allowed to access or modify its own threads and threads in any descendant thread groups, but nothing else.

void checkAccess(Thread t): Checks if the current thread is allowed to modify the state of the thread t
void checkAccess(ThreadGroup tg): Checks if the current thread is allowed to modify the state of the thread group tg

Q52. Popular Threading Implementations
Ans.
1. Green Threads: This is the simplest. Here, OS doesn't know anything about Java threads at all; it is up to the virtual machine to handle all the details of the threading API. From OS perspective, there is a single process and a single thread.

Each thread in this model is an abstraction within the JVM and this must hold all information related to that thread. JVM itself is responsible for switching thread contexts. As far as OS is concerned, fact that the code is emulating many different threads is unknown outside of the JVM.

2 Windows Native Threads: In the native-threading model used on 32-bit Windows OS, OS is fully cognizant of the multiple threads that the virtual machine uses, and there is a one-to-one mapping between Java threads and operating system threads. Therefore, the scheduling of Java threads is subject to the underlying scheduling of threads by the OS.

This model is usually simple to understand because every thread can be thought of as a process. The OS scheduler makes no real distinction in this case between a process and a thread: it treats each thread like a process. Of course, there are still other differences in the OS between a thread and a process, but not as far as the scheduler is concerned.

Windows OS uses a complex priority calculation to determine which thread should be the currently running thread. That calculation takes into account the Windows thread priority. This is very similar to the Java-level thread priority between 0 and 10, except that Windows provides only 7 priorities. Therefore, some overlap occurs as Java's 11 logical priorities are mapped to Windows 7 actual priorities. Different implementations of the virtual machine do this differently.

The upshot of all this is that it's very difficult to guarantee explicitly ordered thread execution on Windows platforms, but the complex priority calculation ensures that threads do not starve.

3. Solaris Native Threads: Recent versions of the Solaris Operating Environment have had two different threading models. Solaris 7 featured a complex, two-level threading system, with user-level threads and system-level lightweight processes (LWPs). Java threads were equivalent to Solaris user-level threads, and there is an M-to-N mapping between the user-level threads and LWPs.

In Solaris 9, a new one-to-one threading model is used. That makes it conceptually similar to the models on Windows operating systems, though its implementation details are quite different.

In Solaris 8, both models are available, and the user picks a model when the Java program (or any other program) is executed.

For Java programs, the one-to-one model is highly preferable, particularly when the machine has multiple CPUs and the Java threads are CPU-intensive. In other cases, the one-to-one threading model is still preferred, though the difference in threading models is not as significant.

4. Linux Native Threads: New Linux kernels use the Native Posix Thread Library (NPTL), which provides the same one-to-one mapping of Java threads to kernel threads that we've seen in other operating systems. The complex priority calculation for those threads is similar to what we saw on Solaris, where the Java priority is only a small factor in the calculation.

No comments:

Post a Comment