Translate

Showing posts with label Callable. Show all posts
Showing posts with label Callable. Show all posts

Sunday, December 22, 2013

Executors, Thread pool

Q1. Executor Interfaces
Ans. The java.util.concurrent package defines three executor interfaces:
1. Executor: Simple interface that supports launching new tasks. It provides a single method - execute.
2. ExecutorService: Subinterface of Executor, which adds features that help manage the lifecycle, both of the individual tasks and of the executor itself.
3. ScheduledExecutorService: Subinterface of ExecutorService, supports future and/or periodic execution of tasks.

Executor Interface: However, the definition of execute is less specific. The low-level idiom creates a new thread and launches it immediately. Depending on the Executor implementation, execute may do the same thing, but is more likely to use an existing worker thread to run r, or to place r in a queue to wait for a worker thread to become available.


ScheduledExecutor Interface: Using either schedule() to run a task once or scheduleAtFixedRate() to repeat a task at a regular interval, you set up Runnable objects to be executed at some time in the future.

ExecutorService Interface: The ExecutorService interface supplements execute with a more versatile submit method. Like execute, submit accepts Runnable objects, but also accepts Callable objects, which allow the task to return a value. The submit method returns a Future object, which is used to retrieve the Callable return value and to manage the status of both Callable and Runnable tasks. ExecutorService also provides methods for submitting large collections of Callable objects. Finally, ExecutorService provides a number of methods for managing the shutdown of the executor. To support immediate shutdown, tasks should handle interrupts correctly.

ScheduledExecutorService 
InterfaceThe ScheduledExecutorService interface supplements the methods of its parent ExecutorService with schedule, which executes a Runnable or Callabletask after a specified delay. In addition, the interface defines scheduleAtFixedRate and scheduleWithFixedDelay, which executes specified tasks repeatedly, at defined intervals.

Q2. Difference b/w shutdown() and shutdownNow() of Executor interface.
Ans. The shutdown() and shutdownNow() methods are also part of the thread pool class. The shutdown() method is used to shut down the executor but allows all pending tasks to complete. The shutdownNow() method is used to try to cancel the tasks in the pool in addition to shutting down the thread pool. However, this works differently from a thread pool because of repeating tasks. Since certain tasks repeat, tasks could technically run forever during a graceful shutdown.

Q3. Why do you need Callable Interface
Ans. This introduced in Java SE5, is a generic with a type parameter representing the return value from the method call() and must be invoked using an ExecutorService submit() method.

Callable objects are used only by ExecutorService (not simple executors); the services operate on callable objects by invoking their call() method and keeping track of the results of those calls.

ExecutorService exec = Executors.newCachedThreadPool();
ArrayList<Future<String>> results = new ArrayList<Future<String>>();
for (int i = 0; i < 10; i++)
     results.add(exec.submit(new TaskWithResult(i)));


When you ask an executor service to run a callable object, the service returns a Future object that allows you to retrieve those results, monitor the status of the task, and cancel the task. 


Callable and future objects have a one-to-one correspondence: every callable object that is sent to an executor service returns a matching future object. The get() method of the future object returns the results of its corresponding call() method. The get() method blocks until the call() method has returned (or until the optional timeout has expired). If the call() method throws an exception, the get() method throws an ExecutionException with an embedded cause, which is the exception thrown by the call() method.

The future object keeps track of the state of an embedded Callable object. The state is set to cancelled when the cancel() method is called. When the call() method of a callable task is called, the call() method checks the state: if the state is cancelled, the call() method immediately returns.

When the cancel() method is called, the corresponding callable object may be in one of three states. It may be waiting for execution, in which case its state is set to cancelled and the call() method is never executed. It may have completed execution, in which case the cancel( ) method has no effect. The object may be in the process of running. In that case, if the mayInterruptIfRunning flag is false, the cancel() method again has no effect. If the mayInterruptIfRunning flag is true, however, the thread running the callable object is interrupted. The callable object must still pay attention to this, periodically calling the Thread.interrupted() method to see if it should exit.


Q4. FutureTask Class/Future Interface
Ans. You can associate a Runnable or CALLABLE object with a future result using the FutureTask class. A FutureTask object can hold either an embedded runnable or callable object, depending on which constructor is used to instantiate the object.

public class FutureTask<V> implements Future<V>, Runnable {}
public FutureTask(Callable<V> task);
public FutureTask(Runnable task, V result);

This class is used internally by the ExecutorService. The object returned from the submit() method of an executor service is an instance of this class. You can use this class directly in programs as well. This makes sense when you need to monitor the status of a runnable/callable object within an executor. You can then use the methods of the Future interface to monitor the status of the run()/call() method of the embedded object.

The get() method embedding a callable task returns whatever is returned by the call() method of that embedded object and get() method embedding a runnable object returns whatever object was used to construct the future task object itself.

Q5. What’s the difference b/w execute and submit method of Executor Interface.
Ans. Execute method accepts only Runnable and doesn’t return anything, whereas submit accepts both Runnable and callable and returns a Future object.

Q6. What is the use of Timer CLASS
Ans. 
cancel() method is used to stop the class from being executed. For a repeating task, calling the cancel() method prevents further execution of the class. For tasks that are executed only once, this has no affect if it is already executing. If task is currently running, has already run, or has been previously cancelled, it returns a boolean value of false. For repeating tasks, this method always returns a boolean value of true.

The cancel() method is provided by the Timer class to destroy the timer. All the tasks in the timer are simply cancelled, and no new tasks are allowed to be scheduled. The Timer object can no longer be used to schedule any more tasks. If a task is currently executing, it is allowed to finish; currently executing tasks are not interrupted.

scheduledExecutionTime() method is used to return the time at which the previous invocation of a repeating task occurred, if task is not running now. If the task is currently running, it is the time at which the task began.

There are a few important issues in the timer implementation, particularly for repeated tasks. First, only a single thread executes the tasks. While it is recommended that the tasks executed by the Timer class be short-lived, no check ensures that this is so. This means that if the Timer object is overwhelmed, a task may be executed at a time much later than the specified time. For repeated tasks, the schedule() method does not take this into account. The schedule time is allowed to drift, meaning that the next iteration of the task is based on the previous iteration. This is not very useful if the task is used to maintain a clock or other time-critical task. 

This can be resolved by using scheduleAtFixedRate(). The next iteration of the task scheduled by the scheduleAtFixedRate() method is calculated from when the previous iteration was supposed to execute—not when the previous iteration actually executes, unlike schedule() method which takes into accoutnt when the previous execution actually occurred.

Since scheduleAtFixedRate() doesn't allow task drifting, using it in conjunction with scheduledExecutionTime() gives added advantage. It might happen that more than one iteration of the repeated task may be waiting to execute. As a result, a timer task may want to skip a particular execution if it knows that another execution is pending in the queue.

Q7. Why do we need scheduled executors. Why can’t we use Timer class.
Ans.
1. Timer class starts only one thread. While it is more efficient than creating a thread per task, it is not an optimal solution. The optimal solution may be to use a number of threads between one thread for all tasks and one thread per task.

2. TimerTask class is not necessary. It is used to attach methods to the task itself, providing the ability to cancel the task and to determine the last scheduled time. This is not necessary - it is possible for the timer itself to maintain this information. It also restricts what can be considered a task. Classes used with the Timer class must extend the TimerTask class; this is not possible if the class already inherits from another class. ScheduledExecutor is much more flexible to allow any Runnable object to be used as the task to be executed.

3. Relying upon the run() method is too restrictive for tasks. run() method has no return variable, nor can it throw any type of exceptions other than run-time exceptions (and even if it could, the timer thread wouldn't know how to deal with it).

ScheduledThreadPoolExecutor class solves all three of these problems. It uses a thread pool and allows the developer to specify the size of the pool. It can work with both Runnable and Callable objects whereas Timer can work only with Runnable objects. It has 3 methods:
1. schedule() method is used to schedule a one-time task.
2. scheduleAtFixedRate() method is used to schedule a repeated task that is not allowed to drift. This is basically the same scheduling model as scheduleAtFixedRate() method of Timer class.
3. scheduleWithFixedDelay() method is used to schedule a repeated task where the period between the tasks remains constant; this is useful when the delay between iterations is to be fixed.
Ex: This model is better for animation since there is no reason to have animation cycles accumulate if the start times drift. If one cycle of the animation runs late, there is no advantage to running the next cycle earlier.

NOTE: schedule() can be used for Callable objects latter two methods don't have Callable support.

Q8. Why do and don’t we need a Thread Pool.
Ans.
Benefits of Thread Pool
1. Overhead of creating a thread is very high; by using a pool, we can gain some performance when the threads are reused. The degree to which this is true depends a lot on your program and its requirements. Creating a thread can take as much as a few hundred microseconds, which is a significant amount of time for some programs but not for all.
2. It allows for better program design. If your program has a lot of tasks to execute, its better to keep the thread management separate to thread pool, thus focusing only on program logic. With a thread pool, you simply create a task and send the task to the pool to be executed; this leads to much more elegant programs.

Disadvantages of Thread Pool
If your program is doing batch processing, or simply providing a single answer or report, i.e. intermediate results are not of concern, it doesn't really matter if you use as many threads as possible or a thread pool. That doesn't mean that you can expect to create thousands of threads with impunity, as threads take memory and this will have impact on system performance. Still, if your program design nicely separates into multiple threads and you're interested only in the end result of all those threads, a thread pool isn't necessary.

Thread pools are also not necessary when available CPU resources are adequate to handle all the work the program needs to do. In fact, in this case a thread pool may do more harm than good. Obviously, if your system has eight CPUs and you have only four threads in your thread pool, tasks wait for a thread even though four CPUs are idle. With a thread pool, you want to throttle the total number of threads so that they don't overwhelm your system, but you never want to have fewer runnable threads than CPUs.

Q9. How do thread pools work.
Ans. Thread pool is constructed with M core threads and N maximum threads. Usually at beginning, no threads are actually created though you can specify to pool to create the threads or core thread. 

A task enters the pool (via the thread pool's execute() method). Now one of five things happens:
1. If the pool has created less than M threads, it starts a new thread and runs the new task immediately. Even if some of the existing threads are idle, a new thread is created in the pool's attempt to reach M threads.
2. If the pool has between M and N threads and one of those threads is idle, the task is run by an idle thread.
3. If the pool has between M and N threads and all the threads are busy, the thread pool examines the existing work queue. If the task can be placed on the work queue without blocking, it's put on the queue and no new thread is started.
4. If the pool has between M and N threads, all threads are busy, and the task cannot be added to the queue without blocking, the pool starts a new thread and runs the task on that thread.
5. If the pool has N threads and all threads are busy, the pool attempts to place the new task on the queue. If the queue has reached its maximum size, this attempt fails and the task is rejected. Otherwise, the task is accepted and run when a thread becomes idle (and all previously queued tasks have run).

Q10. Talk about CachedThreadPool and FixedThreadPool 
Ans. CachedThreadPool: It will generally create as many threads as it needs during the execution of a program and then will stop creating new threads as it recycles the old ones.

FixedThreadPool: With the FixedThreadPool, you do expensive thread allocation once, up front, and you thus limit the number of threads. This saves time because you aren't constantly paying for thread creation overhead for every single task.

A SingleThreadExecutor is like a FixedThreadPool with a size of one thread. This is useful for anything you want to run in another thread continually (a long-lived task), such as a task that listens to incoming socket connections. Thus, a SingleThreadExecutor serializes the tasks that are submitted to it, and maintains its own (hidden) queue of pending tasks.

Executors.newCachedThreadPool();
Executors.newFixedThreadPool(5);

Return type of both is ExecutorService.


Q11. Does calling cancel method on a Thread object in a thread pool removes it from queue.
Ans. When an object in a thread pool is cancelled, there is no immediate effect: the object still remains queued for execution. When the thread pool is about to execute the object, it checks the object's internal state, sees that it has been cancelled, and skips execution of the object. So, cancelling an object on a thread pool queue does not immediately make space in the thread pool's queue. Future calls to the execute() method may still be rejected, even though cancelled objects are on the thread pool's queue: the execute() method does not check the queue for cancelled objects.

One way to deal with this situation is to call the purge() method on the thread pool. The purge() method looks over the entire queue and removes any cancelled objects. One caveat applies: if a second thread attempts to add something to the pool (using the execute() method) at the same time the first thread is attempting to purge the queue, the attempt to purge the queue fails and the canceled objects remain in the queue. A better way to cancel objects with thread pools is to use the remove() method of the thread pool, which immediately removes the task from the thread pool queue. The remove() method can be used with standard runnable objects.


Q12. What happens when current task completes execution and there are no more tasks on queue to run.
Ans. If no tasks are on the queue, one of two things happens:
1. If the pool has more than M threads, the thread waits for a new task to be queued. If a new task is queued within the timeout period, the thread runs it. If not, the thread exits, reducing the total number of threads in the pool. The timeout period is a parameter used to construct the thread pool.
Note: If the specified timeout is 0, the thread always exits, regardless of the requested minimum thread pool size.

2. If the pool has M or fewer threads, the thread blocks indefinitely waiting for a new task to be queued (unless the timeout was 0, in which case it exits). It runs the new task when available. 

Q13. What is the importance of pool size and queue used in Thread Pools. Ans. Choice of pool size and queue are important to getting the behavior you want. For a queue, you have three choices:
1. A SynchronousQueue, which effectively has a size of 0. In this case, whenever the pool tries to queue a task, it fails. The implication of this is tasks are either run immediately or are rejected immediately. Note that you can prevent rejection of a task if you specify an unlimited maximum number of threads, but this prevents the throttling benefit of using a thread pool in the first place.

2. An unbounded queue, such as a LinkedBlockingQueue with an unlimited capacity. In this case, adding a task to the queue always succeeds, which means that the thread pool never creates more than M threads and never rejects a task.

3. A bounded queue, such as a LinkedBlockingQueue with a fixed capacity or an ArrayBlockingQueue. Let's suppose that the queue has a bounds of P. As tasks are added to the pool, it creates threads until it reaches M threads. At that point, it starts queuing tasks until the number of waiting tasks reaches P. As more tasks are added, the pool starts adding threads until it reaches N threads. If we reach a state where N threads are active and P tasks are queued, additional tasks are rejected.

Q14. What happens to rejected tasks.

Ans. Depending on the type of queue you use in the thread pool, a task may be rejected by the execute() method. Tasks are rejected if the queue is full or if the shutdown() method has been called on the thread pool.

When a task is rejected, the thread pool calls the rejected execution handler associated with the thread pool. There is one rejected execution handler for the entire pool; it applies to all potential tasks. You can write your own rejected execution handler, or you can use one of four predefined handlers. Appropriate rejected execution handler then takes an appropriate action when a task is rejected.


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.