Important points about Thread in Java
java.lang.Thread class but JVM plays an important role of all Thread activities. Thread is used to execute task in parallel and this task is coded inside run() method of Runnable interface. You can create Thread in Java programming language by either extending Thread class , implementing Runnable or by using Executor framework in Java. Remember Runnable doesn't represent Thread actually its a task which is executed by Thread. Read more about extends Thread vs implements Runnable here.
1. Thread in Java represent an independent path of execution. (classic definition but I still like it). Thread is represented by
2. During its life time thread remains on various Thread states like NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING which describe what thread is doing. NEW means thread is just created but not yet stated, RUNNABLE means thread is started but waiting for CPU to be assigned by thread scheduler. BLOCKED, WAITING and TIMED_WAITING means thread is not doing anything instead its been blocked and waiting for IO to finished, class or object lock, or any other thread etc.
3. There are two kinds of Thread in Java daemon or non daemon (also called user threads). Java programs runs until there is at least one non-daemon thread exists. First non-daemon thread started by JVM is main thread which is created by JVM and responsible for executing code inside main method in Java. This is called "VM thread" in HotSpot Virtual Machine. Any thread created using java.lang.Thread start() methods from main thread is by default non-daemon but you can make it daemon by calling setDaemon(true) method. Newly created thread in Java inherits daemon property from the thread which creates it. Since main thread is non-daemon, any thread created by it by default remains non-daemon.
4. Every Java threads has priority and name. You can set priority and assign meaningful name while creating object of java.lang.Thread class in Java. its recommend practice to give every thread a meaningful name while creating it , it helps later when you debug your Java program or take thread dump for analysis. Otherwise Java will give your Thread default name like "Thread-number" if Thread is created using java.lang.Thread or "pool-number-thread-number" if Thread is created using ThreadFactory. In Java higher priority thread get preference in Execution over lower priority thread. you can check priority by using method like getProiroty() from thread class.
5.Creation of thread is a time-consuming job so having a Thread pool for performing task concurrently is modern day requirement of performance and scalability. Java 5 provides Executor framework which encapsulate task of creating and managing thread from application code. Consider using Thread pool if your application requires to handle load. In web and application server manages this thread pool because each request is processed in its own thread.
6. Thread.sleep() method is used to pause thread for specified duration. It is an overloaded method defined in java.lang.Thread class. On the other hand Thread.join() is used to wait for another thread to complete its task before running and yield() method is used to relinquish CPU so that other thread can acquire it. See difference between sleep, wait and yield for details.
7. wait() and notify() methods are used to communicate between two threads i.e. for inter thread communication in Java. Always check condition of wait() method in loop and call them from synchronized context. wait() is a method which is defined in object class, and puts the current thread on hold and also releases the monitor (lock) held by this thread, while notify() and notifyAll() methods notifies all thread waiting on that monitor. There is no guarantee which thread will picked up by thread scheduler and given CPU to execute because of of notification. To learn more about how to use wait, notify and notifyAll method to achieve inter-thread communication, see my post about solving producer consumer problem in Java using wait and notify method.
8. Thread scheduling is done by Thread Scheduler which is platform dependent and stays inside JVM. There is no known way to control thread scheduler from Java and many of thread related decision is done by scheduler like if there are many threads is waiting then which thread will be awarded CPU.
9. Thread.isActive() method is used to check whether a thread is active or not. A thread is said to be active until it has not finished either by returning from run() method normally or due to any exception. Thread.holdsLock() method is used to check if a thread holds a lock or not. See how to check if thread holds lock or not for more details.
10. Every thread in Java has its own stack, which is used to store local variables and method calls. Size of this stack can be controlled using -XX:ThreadStackSize JVM option e.g. -XX:ThreadStackSize=512.
11. Java 5 introduced another way to define task for threads in Java by using Callable interface. It's similar to Runnable interface but provides some more capability e.g. it can return result of task execution, which was not possible in Runnable, because return type of run() method was void. Like its predecessor it define a call() method which can return Future<T> object, you can call get() method on this object to get the result of task execution. To learn more about Callable, please see difference between Runnable and Callable interface in Java.
12. Java provides interrupt() method to interrupt a thread in Java. You can interrupt a running thread, waiting thread or sleep thread. This is the control Java provides to prevent a blocked or hanged thread. Once you interrupt a thread, it will also throw InterruptedException, which is a checked exception to ensure that your code should take handle interrupts
13. Java provides two ways to achieve mutual exclusion in your code, either by using synchronized keyword or by using java.util.concurrent.lock implementations. Former is more popular and oldest way to achieve mutual exclusive code but Lock interface is more powerful and provides fine grained control and only available from Java 5, Tiger. You can use synchronized keyword to either make an entire method mutual exclusive or only critical section by declaring a synchronized block. Any thread needs to hold monitor or lock, required by that critical section in order to enter into synchronized block or method, they release that lock, once they exit, either normally or abruptly due to any error. Acquisition and release of monitor is done by Java itself, so its safe and easy for Java programmer, on the other hand if you decide to use Lock interface, you need to explicitly acquire lock and release it, this requires more caution. Popular idiom is to release the lock in finally block. See my post how to use ReentrantLock in Java for code example and few more details.
14. One more thing to know about Thread in Java is that its not started when you create object of Thread class e.g.
Thread t = new Thread();
In fact thread is started when you call start() method of java.lang.Thread class e.g. t.start() will start the thread. It puts your thread in RUNNABLE state and when thread scheduler assign CPU to this thread, it executes run() method. By default run() method Thread class is empty, so you need to override it to do some meaningful task.
That's all on important points related to Thread in Java. You can also suggests points, which you think its been missed here and I will include them in this list to make it more comprehensive and useful. I will also aim to keep it updated with more points once and when I recall or get aware of any stuff related to thread in Java. Last but not the least Effective Java book also got some good advice about synchronization and threads, worth reading for all kinds of Java developers.