A new thread of execution starts (with a new call stack).
The thread moves from the new state to the runnable state.
When the thread gets a chance to execute, its target run() method will run.
A thread is done being a thread when its target run() method completes.
Once a thread has been started, it can never be started again.
t.sleep(); or t.yield() both are actually static methods of the Thread class—they don't affect the instance t; instead they are defined to always affect the thread
that's currently executing.
Remember that sleep() is a static method, so don't be fooled into thinking that
one thread can put another thread to sleep. You can put sleep() code anywhere, since all code is being run by some thread. When the executing code (meaning the currently running thread's code) hits a sleep() call, it puts the currently running thread to sleep.
A thread gets a default priority that is the priority of the thread of execution that creates it. For example, in the code
public class TestThreads {
public static void main (String [] args) {
MyThread t = new MyThread();
}
}
the thread referenced by t will have the same priority as the main thread, since
the main thread is executing the code that creates the MyThread instance.
The yield( ) Method So what does the static Thread.yield() have to do with all this? Not that much, in practice. What yield() is supposed to do is make the currently running thread head back to namable to allow other threads of the
same priority to get their turn. So the intention is to use yield() to promote
graceful turn-taking among equal-priority threads. In reality, though, the yield()
method isn't guaranteed to do what it claims, and even if yield() does cause a
thread to step out of running and back to runnable, there's no guarantee the
yielding thread won't just be chosen again over all the others! So while yield()
might—and often does—make a running thread give up its slot to another runnable thread of the same priority, there's no guarantee.
A yield() won't ever cause a thread to go to the waiting/sleeping/ blocking state.
At most, a yield() will cause a thread to go from running to runnable, but again,
it might have no effect at all.
The non-static join() method of class Thread lets one thread "join onto the end" of another thread. If you have a thread B that can't do its work until another thread A has completed its work, then you want thread B to "join" thread A. This means that thread B will not become runnable until A has finished (and entered the dead state).
Once a thread acquires the lock on an object, no other thread can enter any of the synchronized methods in that class.
If a class has both synchronized and non-synchronized methods,multiple threads can still access the class's non-synchronized methods! If you have methods that don't access the data you're trying to protect, then you don't need to synchronize them.
A thread can acquire more than one lock. For example, a thread can enter a synchronized method, thus acquiring a lock, and then immediately invoke a synchronized method on a different object, thus acquiring that lock as well. As the stack unwinds, locks are released again. Also, if a thread acquires a lock and then attempts to call a synchronized method on that same object, no problem. The JVM knows that this thread already has the lock for this object, so the thread is
free to call other synchronized methods on the same object, using the lock the thread already has.
When a thread is executing code from within a synchronized block, including
any method code invoked from that synchronized block, the code is said to be
executing in a synchronized context. The real question is, synchronized on what?
Or, synchronized on which object's lock?
When you synchronize a method, the object used to invoke the method is the
object whose lock must be acquired. But when you synchronize a block of code,
you specify which object's lock you want to use as the lock, so you could, for
example, use some third-party object as the lock for this piece of code. That gives you the ability to have more than one lock for code synchronization within a single object.