Threads

1) What is a thread?

A thread is a set of instructions executing apart from other threads (with its own stack) but sharing the same memory space (with the same heap).
2) How do I create a new thread and have it start running?

Creating a thread involves creating a new Thread and invoking its start() method. Calling start() causes the run() method of the Thread subclass or the Runnable object passed to the Thread constructor to execute.

Thread t1 = new Thread() {
public void run() {
for (int i=0; i<100; i++) {
System.out.println("Tastes Great");
}
}
};

Runnable r = new Runnable() {
public void run() {
for (int i=0; i<100; i++) {
System.out.println("Less Filling");
}
}
};
Thread t2 = new Thread(r);

t1.start();
t2.start();
3) How do I get a thread to pause?

The static sleep() method of the Thread class will let your thread sleep for a set number of milliseconds (or nanoseconds). When the thread wakes up, it will be scheduled to execute in the future. It may not start executing immediately after the timeout.

try {
Thread.sleep(3000); // 3 seconds
} catch (InterruptedException e) {
System.err.prinlnt("You interrupted me");
}
[
You can have another thread wake up the sleeping thread prematurely by calling t.interrupt() (where "t" is a pointer to the thread object).
Note that since Thread.sleep is a static method, the following code will not do what you expect it to:

Thread t = new MyThread();
t.start();
try {
t.sleep(3000);
} catch (InterruptedException e) {
System.err.prinlnt("You interrupted me");
}
It will pause the current thread, meaning the thread executing the shown code, not the child thread (t/MyThread).

Non-static synchronized methods synchronize on the instance (this) of the class.
4) What object does static synchronized methods use for locking?

Static synchronized methods synchronize on the class object (this.getClass()) of the class.
5) How can one thread wait for another thread to die before it continues execution?

The thread's join() method allows you to wait for another thread to finish execution.

Thread t1 = new Thread(runnable);
t1.start();
// do stuff
...
// wait for t1 to finish
t1.join()
6) What is the use of start () function in starting a thread? Why we do not use the run() funtion directly to run the thread?

The start() method tells the Java Virtual Machine that it needs to create a system specific thread. After creating the system resource, it passes the Runnable object to it to execute its run () method. Calling the run() method directly has the "Thread" execute in the same thread as the calling object, not in a separate thread of execution, as intended.
In other words, calling run() is just like a normal method call. Whereas, calling start() tells the thread to create the necessary system resources and then execute the run() method asynchronously.

7) What is the main difference between a preemptive scheduler and a non-preemptive scheduler?

A preemptive scheduler interrupts a thread of execution when its timeslice runs out. A non-preemptive (or "cooperative") scheduler waits for the thread to yield control.
[Java native thread implementations are usually preemptive; the green-threads implementation is cooperative but priority-preemptive, which means that when a high-priority thread becomes runnable, it immediately becomes active. -Alex]
8) How does a preemptive scheduler manage a thread's timeslice?

The lowest level preemptive scheduler (kernel layer) uses the system timer interrupt and context switching to manage timeslices. When any CPU interrupt occurs, the CPU makes a note of where it was, and what it was doing (pushes all registers onto the stack). The CPU then processes the interrupt and returns to what it was previously doing (pops all registers from the stack). The thread context in this sense, is the information the CPU needs to start or resume execution in any section of code. The scheduler is invoked by the timer interrupt routine (it can also be part of the timer interrupt). The scheduler checks to see if the current timeslice has expired; if so, the current thread context is stored and the next valid thread context is restored. The most basic implementation is a stack swap, as each thread has its own stack. When a thread is created, it gets a new context with an empty stack. The new context directs the CPU to the thread's run() member at the beginning of its timeslice. A thread's context is destroyed when the thread returns from the run() member, or its stop() member is successfully invoked.
9) What are the differences between extending the Thread class and implementing the Runnable interface?

Extending the Thread class will make your class unable to extend other classes, because of the single inheritence feature in JAVA. However, this will give you a simpler code structure. If you implement runnable, you can gain better object-oriented design and consistency and also avoid the single inheritance problems.
10) What are the different uses of the synchronized keyword?

The keyword synchronized is used to acquire a exclusive monitor lock on an object. It can be used to mark either a method or a block of code. In both cases, it means to acquire a lock for the duration of the method or block, and to release the lock at the end. It also takes a parameter, which names the object whose lock will be acquired. (The parameter is implicit when marking a method, as shown below.)

synchronized (foo) {
...
}
Acquires a lock on the object instance "foo" at the open brace, and releases the lock at the close brace.

synchronized (this) {
...
}
Acquires a lock on the current object instance ("this") at the open brace, and releases the lock at the close brace.

synchronized void bar() {
...
}
Acquires a lock on the current object instance at the open brace, and releases it at the close brace. This is equivalent (*) to
void bar() {
synchronized (this) {
...
}
}

class Foo {
synchronized static void bar() {
...
}
}
Acquires and releases a lock on the class instance of class Foo. Every class, when loaded, is given an instance of class Class. That means that no matter who invokes method Foo.bar(), the lock will be on the static instance, and not on any specific instance of class Foo.
I know this sounds confusing, but it has the same semantics as any other use of static: all statics (methods, variables, etc) are essentially global, interact with all other statics of the same class, and do not interact with non-static instance data.
Whether a method is public or not makes no difference to the semantics of synchronized.
11) How can multiple threads be controlled simultanesously?

If you create threads in a ThreadGroup object, they may be controlled simultaneously with the member functions of said object.
12) What is a daemon thread? When should I use setDaemon() and why?

Use thread.setDaemon(true) to tell the JVM to make the thread a daemon thread.
According to Webster's, a daemon (variant of demon) is an attendant power or spirit. Daemon threads are typically used to perform services for your application/applet (such as loading the "fiddley bits"). The core difference between user threads and daemon threads is that the JVM will only shut down a program when all user threads have terminated. Daemon threads are terminated by the JVM when there are no longer any user threads running, including the main thread of execution. Use daemons as the minions they are.
[In short: daemon threads do not keep the program from quitting; user threads keep the program from quitting. -Alex]
13) What is the difference between sleep(), wait() and suspend()?

Thread.sleep() sends the current thread into the "Not Runnable" state for some amount of time. The thread keeps the monitors it has aquired -- i.e. if the thread is currently in a synchronized block or method no other thread can enter this block or method. If another thread calls t.interrupt() it will wake up the sleeping thread.
Note that sleep is a static method, which means that it always affects the current thread (the one that is executing the sleep method). A common mistake is to call t.sleep() where t is a different thread; even then, it is the current thread that will sleep, not the t thread.
t.suspend() is deprecated. Using it is possible to halt a thread other than the current thread. A suspended thread keeps all its monitors and since this state is not interruptable it is deadlock prone.
object.wait() sends the current thread into the "Not Runnable" state, like sleep(), but with a twist. Wait is called on a object, not a thread; we call this object the "lock object." Before lock.wait() is called, the current thread must synchronize on the lock object; wait() then releases this lock, and adds the thread to the "wait list" associated with the lock. Later, another thread can synchronize on the same lock object and call lock.notify(). This wakes up the original, waiting thread. Basically, wait()/notify() is like sleep()/interrupt(), only the active thread does not need a direct pointer to the sleeping thread, but only to the shared lock object.
[This answer was edited; the original answer was clear but I felt I should expand on some points; please blame me, not Ingo, for any errors. -Alex]
14) What is the difference between a lightweight and a heavyweight process?

[Short answer: threads are lightweight, programs (aka processes or tasks) are heavyweight. -Alex]
Lightweight and heavyweight processes refer the mechanics of a multi-processing system.
In a lightweight process, threads are used to divvy up the workload. Here you would see one process executing in the OS (for this application or service.) This process would posess 1 or more threads. Each of the threads in this process shares the same address space. Because threads share their address space, communication between the threads is simple and efficient. Each thread could be compared to a process in a heavyweight scenario.
In a heavyweight process, new processes are created to perform the work in parallel. Here (for the same application or service), you would see multiple processes running. Each heavyweight process contains its own address space. Communication between these processes would involve additional communications mechanisms such as sockets or pipes.
The benefits of a lightweight process come from the conservation of resources. Since threads use the same code section, data section and OS resources, less overall resources are used. The drawback is now you have to ensure your system is thread-safe. You have to make sure the threads don't step on each other. Fortunately, Java provides the necessary tools to allow you to do this.

15) What is the meaning of calling a method or object "thread-safe?"

Basically, calling a method "thread-safe" means that even if multiple threads try to access it simultaneously, nothing bad happens. Here "bad" usually means that due to race conditions, or deadlock, or other pitfalls, the object's state gets corrupted, or its methods produce unreliable results. A method usually acheives thread-safety by protecting access to shared resources. This usually translates to using the Java synchronized keyword to protect blocks of code that access instance variables, or other shared variables.
For an object to be thread-safe, it must be possible for multiple threads to simultaneously access the same method, or multiple methods, in that object. Usually this is acheived by assuring that each method is thread-safe, but this doesn't always suffice, since methods can call each other in strange ways, leading to deadlock and other weirdness.
It is very difficult to prove that an object is thread-safe. The main rule of thumb for making thread-safe objects is, "Make all the instance variables private, and all the public accessor methods synchronized." However, this is sometimes difficult to achieve in practice, due to exigencies of performance, architecture, or implementation.
Accurate multithreaded programming is a true art, and very difficult to master. Read "Java Threads" by Oaks and Wong, and "Concurrent Programming in Java" by Lea, for inspiration in your quest to become a thread-safe programmer.

16) How can I actually, really deallocate a Thread to release the memory? Setting thread = null does not work!

Using thread = null will not release a running thread. In order to release the memory associated with a thread, you need to make sure that all of the following are done:
 Make sure that the thread's start() method has been called.
 Make sure that the thread has stopped executing.
 Clear any references to that Thread object (thread = null;).
This is the best you can do to ensure the release of memory for a Thread. You have to call start() on the thread because several JVMs have a bug where they will not release all the thread's memory if the thread is not started.
17) What is the difference between a thread and a process?

A process is an OS-level task or service. A thread runs "inside" a process and may be virtual or simulated. Generally speaking, threads share resources like memory, where processes each have their own separate memory area, and need to take more elaborate steps to share resources.
Another name for thread is "lightweight process" to distinguish it from the "heavyweight" system processes.

18) What is the difference between threads and interrupts ?

A thread is a CPU's state of execution as it processes a set of instructions (also referred to as a task). An interrupt is a condition that causes the CPU to store the state of its current thread of execution to begin a more important task, or to begin or resume the next task in a list of tasks. An interrupt handler is the set of CPU instructions associated with any given interrupt (a PC has several types of interrupts).
The confusing part is the fact that the thread of execution in an interrupt handler is often referred to as an interrupt.
In short, a thread is a task and an interrupt is a signal used to queue a more important task.
19) When and why is IllegalMonitorStateException thrown?

According to the JavaDoc, IllegalMonitorStateException is thrown "to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor."
20) What is deadlock? How can I eliminate it?

A simple deadlock situation is one in which a two threads are waiting. Each thread waiting for a resource which is held by the other waiting thread. [In Java, this resource is usually the object lock obtained by the synchronized keyword.]
This deadlock situation can range from the above two thread situation to any number of threads waiting in a circular fashion.
Many solutions to this well known problem have been defined over the years including the large range of solutions to "The Dining Philosophers" problem.
21) What is InterruptedException? Why do we need to catch it when calling Thread.sleep()?

InterruptedException is thrown if another thread calls interrupt() on the sleeping thread while it is asleep. If sleep() is setting an alarm clock before bed, interrupt() is a midnight phone call.
This means that you can safely ignore the exception (with catch (InterruptedException e) {}) since in general, only code that you write will ever call interrupt. Since you didn't write it, you know it won't happen. :-)
InterruptedException was not implemented in Java 1.0; however, it is definitely available now.
The exception will also get thrown if the "interrupted" flag is set in the thread, which happens if another thread calls interrupt even before the original thread sleeps.
22) When exactly is the AWT thread started?

Anytime the java.awt.Toolkit instance is (directly or indirectly) created. The direct way to create it is by calling-
Toolkit.getDefaultToolkit();
Indrect way is by creating any AWT object.
Here is a sample program to play with -

import java.awt.*;
public class X
{
static Frame f;

public static void main(String[] args)
{
//Toolkit.getDefaultToolkit();
f = new Frame();
System.out.println("...");
}
}

23) What is the difference between multithreading and multitasking? What about multiprogramming? Multiprocessing?

Multitasking is running multiple "heavyweight" processes (tasks) by a single OS.
Multithreading is running multiple "lightweight" processes (threads of execution) in a single process / task / program. See What is the difference between a lightweight and a heavyweight process? for more detail on lightweight vs. heavyweight processes.
Multiprogramming is essentially a synonym for multitasking (though multitasking connotes sharing more resources than just the CPU, and is the more popular term).
Multiprocessing involves using multiple CPUs, either in the same (SMP) or different (MPP) host boxes, to run a program. See whatis.com for a good definition.
Most Java implementations will split threads among different processors if they're running on an SMP box.
24) Why is Thread.run() declared public? Shouldn't it be declared protected, as only the Thread superclass can invoke it?

One reason is that Thread implements Runnable, which requires that run() be public. This is an unfortunate consequence of the definition of Java interfaces.
It is also not clear whether you would want to prohibit other classes from calling a Thread's run() method in a synchronous manner -- as it is, they have the option of calling either run() or start() depending on their needs.
25) Is there any method by which I can join() to a group of threads instead of a single one?

Yes. Just join to each one in turn. That way, when the loop exits, you know that all the threads have exited -- whether it was the first thread or the seventh thread that took the longest, all threads will be waited for. Remember, join() on a thread that's already exited takes no time.

Iterator i = myThreads.iterator();
while (i.hasNext()) {
((Thread)i.next()).join();
}
26) Why do I have to call System.exit() from my main method?

Unfortunately, certain system threads are started as regular threads, not daemon threads. One example is the AWT thread. That means that if your app opens a window, then even if that window is closed, the AWT thread continues, so your app will never quit on its own.
There are many cases where a Java program will quit on its own when main() exits, but there are also many sneaky cases where a thread is launched without your knowledge by a library routine. Database Connection Pools are notorious for doing this.
A warning: Make sure you only call System.exit() when you're really really sure all background threads have stopped processing. Otherwise the threads will be stopped prematurely, and may leave things in a bad state (for instance, if they're halfway through writing a file).
27) What is the difference between sleep and yield?

yield() tells the JVM Thread Scheduler that it's OK to give other threads time slices. Usually the JVM uses this call to activate another thread of the same thread priority. In a good preemptive multithreading environment, yield() is a no-op. However, it is important in a cooperative multithreading environment, since without yield(), one thread can eat up all of the CPU.
sleep(x) tells the JVM Thread Scheduler to actively put this thread to sleep and not run it again until at least x milliseconds have elapsed.
Neither sleep() nor yield() change anything about the status of synchronization locks. If your thread has a lock, and you call sleep(1000), then at least a second will elapse before your thread wakes up. When it wakes up it may decide to release the lock -- or it may hold on to it longer.
28) How do we stop the AWT Thread? Our Swing application will not terminate.

You need to explicitly call System.exit(exit_value) to exit a Swing application. This is because the event dispatcher thread is not a Daemon thread, and won't allow the JVM to shut down when other threads are dead.
29) How soon after calling start() will the run() method be executed?

Your run method is not guarenteed to run immediately after the Thread.start () method is called.
The Java Language Specification gives implementations lots of legroom with respect to the scheduling of threads. Your thread may start immediately, or it may start 5 minutes later.
Any decent implementation will have your thread start as soon as possible under the scheduling algorithm, so a five minute wait would be unreasonable.
30) What does it mean to lock an object?

Every object instance in Java has a little piece of data hanging off of it called a "monitor lock." This is similar to a semaphore.
When you use the synchronized keyword, the current thread attempts to obtain the monitor lock for the object in question (either "this" or the object named explicitly). If the lock is unavailable, because another thread has acquired it, then the current thread pauses indefinitely. When it wakes up again, it will have acquired the lock, and will retain it until the end of the code block where synchronized was used.
One confusing part is that the only thing that this lock locks is access to the lock itself. It does not control access to instance variables or method access in and of itself. Other threads can reach in and modify variables and call methods. If you want the lock to control access to variables, then you must explicitly use the synchronized keyword every single place in your code that accesses them.
A straightforward way to guarantee that no variable access happens without a lock is by making all your variables private and using synchronized on all your accessor/mutator methods (getFoo/setFoo).
31) How do I capture an exception stack trace and put it into a string?

Here's how to print the trace in a string:

Exception ex = new Exception("something went wrong");
StringWriter sw = new StringWriter();
ex.printStackTrace(new PrintWriter(sw));
String stacktrace = sw.toString();
System.out.println("stacktrace = " + stacktrace);
32) Is it possible to wake up a sleeping thread?
Call sleepingThread.interrupt().

No comments: