您的位置:首页 > 编程语言 > Java开发

java Thread sleep yield join wait notify notifyAll

2016-04-21 23:51 375 查看
记录一下:

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 the
start()
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 the
start()
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 considered
alive. 

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 only
one
way 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

not
runnable, but it might
return
to a runnable state later if a particular event occurs. A thread may be
blocked 

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 be
sleeping
because the thread's run code
tells
it 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 be
waiting, because the thread's
run code causes
it 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 not
tell another thread to block. Some methods may
look 

like they tell another thread to block, but they don't. If you have a reference
t 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 a
static
method—it's misleading. There
is
a method,suspend(),
in the Thread class, that lets one thread

tell another to suspend,but the
suspend()
method has been deprecated(nor
resume()). There is also a
stop()
method, but

it too has been deprecated and we won't even go there. Both
suspend()and
stop()
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 its
run()
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 invoke
start()
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 be
alive. 

sleep():

The
sleep()
method is a
static
method 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 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 runnable 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. 

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 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). 

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


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

thread) and
joins
it to the end of the thread referenced by
t. This blocks the current thread from
becoming runnable until after

the thread referenced by
t
is no longer alive. In other words, the code
t.join()
means "Join me (the current thread) to the

end of
t, so that
t
must 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 thread
t
is 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 methods
wait() and
notify(), 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 the
wait()
method of the target object. From that moment, it doesn't execute any further 

instructions until the
notify()
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 call
wait() or
notify(), 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 because
notify() is called

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

In most scenarios, it's preferable to notify
all 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 the
right thread

(along with all of the others) gets notified. 

As we said earlier, an object can have many threads waiting on it, and using
notify()
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. 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 线程