java Thread sleep yield join wait notify notifyAll

来源:互联网 发布:2016淘宝网店开店流程 编辑:程序博客网 时间:2024/04/29 07:49

记录一下:

Thread States

A thread can be only in one of five states (see Figure 9-2):

New :

This is the state the thread is in after the Thread instance has been created, but thestart()method has not been

invoked on the thread. It isa live Thread object, but not yet a thread of execution. At this point, the thread is considered 

not alive

Runnable:

This is the state a thread is in when it's eligible to run, but the scheduler has not selected it to be the running thread.

A thread first enters the runnable state when thestart()method is invoked, but a thread can also return to the runnable 

state after either running or coming back from a blocked, waiting, or sleeping state. When the thread is in the runnable 

state,it is consideredalive

Running :

This is it. The "big time." Where the action is. This is the state a thread is in when the thread scheduler selects it (from the 

runnable pool) to be the currently executing process. A thread can transition out of a running state for several reasons,

including because "the thread scheduler felt like it."We'll look at those other reasons shortly. Note that in Figure 9-2, there

are several ways to get to the runnable state, but onlyoneway to get to the running state: the scheduler chooses a 

thread from the runnable pool. 

Waiting/blocked/sleeping:

This is the state a thread is in when it's not eligible to run. Okay, so this is really three states combined into one,
but they all have one thing in common: the thread is still alive, but is currently not eligible to run. In other words, it is

notrunnable, but it mightreturnto a runnable state later if a particular event occurs. A thread may beblocked 

waiting for a resource (like I/O or an object's lock), in which case the event that sends it back to runnable is the 

availability of the resource—for example, if data comes in through the input stream the thread code is reading from, 

or if the object's lock suddenly becomes available. A thread may besleepingbecause the thread's run codetellsit to 

sleep for some period of time,in which case the event that sends it back to runnable is that it wakes up because its sleep

time has expired. Or the thread may bewaiting, because the thread's run code causesit to wait, in which case the 

event that sends it back to runnable is that another thread sends a notification that it may no longer be necessary for the

thread to wait. The important point is that one thread does nottell another thread to block. Some methods maylook 

like they tell another thread to block, but they don't. If you have a referencet to another thread, you can write something

like this: 

t.sleep();   or     t.yield()

But those 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. (This is a good example of why it's a bad idea to use an instance 

variable to access astaticmethod—it's misleading. Thereisa method,suspend(), in the Thread class, that lets one thread

tell another to suspend,but thesuspend()method has been deprecated(norresume()). There is also astop()method, but

it too has been deprecated and we won't even go there. Bothsuspend()andstop()turned out to be very dangerous, so

you shouldn't use them. Don't study 'em, don't use 'em. Note also that a thread in a blocked state is still considered to be 

alive


Dead :

A thread is considered dead when itsrun()method completes. It may still be a viable Thread object, but it is no longer a 

separate thread of execution. Once a thread is dead, it can never be brought back to life! (The whole "I see dead threads"

thing.) If you invokestart()on a dead Thread instance, you'll get a runtime (not compiler) exception. And it probably 

doesn't take a rocket scientist to tell you that if a thread is dead, it is no longer considered to bealive


sleep():

Thesleep()method is astaticmethod of class Thread. You use it in your code to "slow a thread down" by forcing it

to go into a sleep mode before coming back to runnable (where it still has to beg to be the currently running thread). 

When a thread sleeps, it drifts off somewhere and doesn't return to runnable until it wakes up. 


yield():

In most JVMs, however, the scheduler does use thread priorities in one important way: If a thread enters the runnable

state, and it has a higher priority than any of the threads in the pool and a higher priority than the currently running thread,

the lower-priority running thread usually will be bumped back to runnable and the highest-priority thread will be chosen to

run. In other words, at any given time the currently running thread usually will not have a priority that is lower than any of 

the threads in the pool.In most cases, the running thread will be of equal or greater priority than the highest priority threads 

in the pool.This is as close to a guarantee about scheduling as you'll get from the JVM specification, so you must never rely

on thread priorities to guarantee the correct behavior of your program. 

So what does thestatic Thread.yield()have todo with all this? Not that much, in practice. Whatyield()is supposed

to do is make the currently running thread head back to runnable to allow other threads of the same priority to get their turn.

So the intention is to useyield()to promote graceful turn-taking among equal-priority threads. In reality, though, theyield()

method isn't guaranteed to do what it claims, and even ifyield()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 whileyield()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, ayield()will cause a thread to

go from running to runnable, but again, it might have no effect at all. 


join():

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 threadA has completeditswork, 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). 

Thread t = new Thread();  t.start();  t.join();

The preceding code takes the currently running thread (if this were in themain()method, then that would be the main 

thread) andjoinsit to the end of the thread referenced byt. This blocks the current thread from becoming runnable until after

the thread referenced bytis no longer alive. In other words, the codet.join()means "Join me (the current thread) to the

end oft, so thattmust finish before I (the current thread) can run again." You can also call one of the overloaded versions of

join()that takes a timeout duration, so that you're saying, "wait until threadtis done, but if it takes longer than 5,000millise-

conds, then stop waiting and become runnable anyway." 


wait(),notify(),notifyAll():

wait(), notify(),and notifyAll()must be called from within a synchronized context! A thread can't invoke a wait 

or notify method on an object unless it owns that object's lock. 

The methodswait() andnotify(), remember, are instance methods of Object.In the same way that every object has 

a lock, every object can have a list of threads that are waiting for a signal (a notification) from the object. A thread gets on

this waiting list by executing thewait()method of the target object. From that moment, it doesn't execute any further 

instructions until thenotify()method of the target object is called. If many threads are waiting on the same object, only 

one will be chosen (in no guaranteed order) to proceed with its execution. If there are no threads waiting, then no particular

action is taken. For a thread to callwait() ornotify(), the thread has to be the owner of the lock for that object. When the

thread waits, it temporarily releases the lock for other threads to use, but it will need it again to continue execution. When the

wait()method is invoked on an object, the thread executing that code gives up its lock on the object immediately. However, 

when notify() is called,that doesn’t mean the thread gives up its lock at that moment. If the thread is still completing 

synchronized code, the lock is not released until the thread moves out of synchronized code. So just becausenotify() is called

doesn’t mean the lock becomes available at that moment. 

In most scenarios, it's preferable to notifyall of the threads that are waiting on a particular object. If so, you can use 

notifyAll() on the object to let all the threads rush out of the waiting area and back to runnable. This is especially important

if you have several threads waiting on one object, but for different reasons, and you want to be sure that theright thread

(along with all of the others) gets notified. 

As we said earlier, an object can have many threads waiting on it, and usingnotify()will affect only one of them. Which

one, exactly, is not specified and depends on the JVM implementation, so you should never rely on a particular thread being 

notified in preference to another. 



 

0 0
原创粉丝点击