A thread life cycle contains states, i.e. NEW, RUNNABLE, TERMINATED, WAITING, TIMED-WAITING, BLOCKED, where RUNNABLE consists of two states, i.e. READY, and RUNNING.
NEW: a thread is created, but not started yet.
BLOCKED: a thread is blocked and waiting for a monitor lock.
TIMED_WAITING: a thread waiting for another to perform a particular action for a specified time.
It depends upon the underlying OS. Scheduler decides when to pick up a thread and make it running in JVM, but not a developer. So a thread running may feel like randomly.
When a thread start() method is called, it moves a thread from NEW to RUNNABLE_READY. The underlying scheduler moves a thread from READY to RUNNING, vice versa. Even we set a thread as the highest priority, it won't guarantee to make it running at once. The thread scheduler may ignore the thread that having the highest priority. In some sense, threads run randomly. When a thread runs out a sliced time of CPU, the thread scheduler may suspend this thread until a next time slice available.
Yield(): it is not guaranteed. It makes a current thread to give up its CPU time.
Sleep(): it is guaranteed to move the current thread from RUNNING to READY for a specific period.
Object Instance Methods:
Wait(): pause Object's execution and wait for another object, i.e. moving to the READY state
Notify(): waking up one waiting thread back to RUNNABLE.
NotifyAll(): waking up all waiting threads back to RUNNABLE.
wait(), notify, and notifyAll() must be called in a synchronized method or code block; or an IllegalMonitorStateException will be thrown.
How to Protect Data and Object Shared by Thread
Unlike the regular process, threads are lightweight processes. They share certain memory areas. When multiple threads access common data variable or objects, we need to consider how to keep their states consistent. You may protect your shared data by (1) restrict it accessible only to one thread at one moment; (2) make objects immutable (3) declaring volatile variables.
How an object is protected?
Using a keyword 'synchronized' to achieve an object's lock. Each Java object is associated with a monitor, which can be a lock or unlocked by a thread. And, only one thread can hold its lock. By this way, the object can be read or write by one thread, so that the data cannot be polluted. When this thread carried out a read or write, it releases the lock. Other threads, therefore, may acquire the lock and access the data object.
In JAVA, a '
synchronized' keyword can be used to modify a method or a statement block.
A 'synchronized' instance method refers to the lock of the class instance.
A 'synchronized' static method refers to the lock of the class.
Using the 'synchronized' method may reduce performance, for several static methods share a common instance or class lock.
Or: instead of using a synchronized method, using a synchronized block within a method. It may avoid the performance issue due to the 'synchronized' method. Synchronized blocks may refer to their own instance locks. So they won't have performance issues due to sharing a common lock like using synchronized methods.
How to make an object immutable?
An immutable data object cannot result in inconsistency, for it cannot be modified externally.
(1) making a class final, so that it cannot be extended and added extra methods to modify fields.
(2) making fields private and final, so that once it is initialized then it cannot be modified later on.
(3) removing all setters.
(4) return a cloned protected field, thus its existing value cannot be modified via its exposed reference
(5) if immutable class hold a mutable class; using a cloned copy of the class from the constructor.
(6) making methods final, thus no method can be overridden. so that, an existing protected field cannot be modified in overriding methods.
What are volatile variables?
All writes to the volatile variables will be written back to main memory immediately. All reads to the volatile variables will be directly read from main memory, rather than local CPU caches.
The 'Volatile' keyword has a limitation: the variable must have no dependency on its previous state. in a short, it must be atomic. For example, if the variable x = x+1, the Volatile keyword won't work. In my understanding, it works when only need to share a flag variable or just value, like a boolean variable, or a number.
What is atomicity or atomic?
We often use this term atomic. Atomicity, it means an indivisible unit, like a transaction. it may keep data consistent. All operations on a data object or variable in the memory are carried out in an enclosed and un-interweaved process. Just like you are seating in an enclosed space alone and accomplish all your homework without any interruption.
What is a happens-before relationship?
it means A must happens before B.
What is deadlock?
Deadlock is a situation, where Thread A is allocated resource R1; meanwhile, thread B is allocated resource R2.
In order to continue their own transaction respectively, thread A asks for R2 and simultaneously thread B asks for R1.
On such a situation, both threads will wait for each other forever.
What is Livelock?
Both thread A and thread B asking for the same lock at the same time. This is exactly like the case when we both call each other at the same via phone, so cannot make the call.