<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-204  評論-149  文章-0  trackbacks-0
    關于Java多線程知識可以看看《Thinking in Java 》中的多線程部分和《Java網(wǎng)絡編程》中第5章多線程的部分

    以下是參考<<Java多線程模式>>的
    1. sleep() & interrupt()
        線程A正在使用sleep()暫停著: Thread.sleep(100000);
        如果要取消他的等待狀態(tài),可以在正在執(zhí)行的線程里(比如這里是B)調(diào)用
            a.interrupt();
        令線程A放棄睡眠操作,這里a是線程A對應到的Thread實例
        執(zhí)行interrupt()時,并不需要獲取Thread實例的鎖定.任何線程在任何時刻,都可以調(diào)用其他線程interrupt().當sleep中的線程被調(diào)用interrupt()時,就會放棄暫停的狀態(tài).并拋出InterruptedException.丟出異常的,是A線程.

    2. wait() & interrupt()
        線程A調(diào)用了wait()進入了等待狀態(tài),也可以用interrupt()取消.
        不過這時候要小心鎖定的問題.線程在進入等待區(qū),會把鎖定解除,當對等待中的線程調(diào)用interrupt()時(注意是等待的線程調(diào)用其自己的interrupt()),會先重新獲取鎖定,再拋出異常.在獲取鎖定之前,是無法拋出異常的.

    3. join() & interrupt()
        當線程以join()等待其他線程結束時,一樣可以使用interrupt()取消之.因為調(diào)用join()不需要獲取鎖定,故與sleep()時一樣,會馬上跳到catch塊里. 注意是隨調(diào)用interrupt()方法,一定是阻塞的線程來調(diào)用其自己的interrupt方法.如在線程a中調(diào)用來線程t.join().則a會等t執(zhí)行完后在執(zhí)行t.join后的代碼,當在線程b中調(diào)用來a.interrupt()方法,則會拋出InterruptedException

    4. interrupt()只是改變中斷狀態(tài)而已
        interrupt()不會中斷一個正在運行的線程。這一方法實際上完成的是,在線程受到阻塞時拋出一個中斷信號,這樣線程就得以退出阻塞的狀態(tài)。更確切的說,如果線程被Object.wait, Thread.join和Thread.sleep三種方法之一阻塞,那么,它將接收到一個中斷異常(InterruptedException),從而提早地終結被阻塞狀態(tài)。
        如果線程沒有被阻塞,這時調(diào)用interrupt()將不起作用;否則,線程就將得到異常(該線程必須事先預備好處理此狀況),接著逃離阻塞狀態(tài)。
        線程A在執(zhí)行sleep,wait,join時,線程B調(diào)用A的interrupt方法,的確這一個時候A會有InterruptedException異常拋出來.但這其實是在sleep,wait,join這些方法內(nèi)部會不斷檢查中斷狀態(tài)的值,而自己拋出的InterruptedException。
        如果線程A正在執(zhí)行一些指定的操作時如賦值,for,while,if,調(diào)用方法等,都不會去檢查中斷狀態(tài),所以線程A不會拋出InterruptedException,而會一直執(zhí)行著自己的操作.當線程A終于執(zhí)行到wait(),sleep(),join()時,才馬上會拋出InterruptedException.
        若沒有調(diào)用sleep(),wait(),join()這些方法,或是沒有在線程里自己檢查中斷狀態(tài)自己拋出InterruptedException的話,那InterruptedException是不會被拋出來的.

    順便加個與Thread.sleep()相同效果的代碼:
    public static void amethod(long x) throws InterruptedExcetion{
        if (x != 0) {
            Object o = new Object();
            synchronized (o) {
                o.wait(x);
            }
        }
    }
    posted on 2009-06-08 21:01 Frank_Fang 閱讀(12814) 評論(5)  編輯  收藏 所屬分類: Java編程

    評論:
    # re: Java多線程sleep(),join(),interrupt(),wait(),notify() 2009-06-08 21:07 | Frank_Fang

    5.5.2 Preemption

    Every virtual machine has a thread scheduler that determines which thread to run at any given time. There are two kinds of thread scheduling: preemptive and cooperative. A preemptive thread scheduler determines when a thread has had its fair share of CPU time, pauses that thread, and then hands off control of the CPU to a different thread. A cooperative thread scheduler waits for the running thread to pause itself before handing off control of the CPU to a different thread. A virtual machine that uses cooperative thread scheduling is much more susceptible to thread starvation than a virtual machine that uses preemptive thread scheduling, since one high-priority, uncooperative thread can hog an entire CPU.

    All Java virtual machines are guaranteed to use preemptive thread scheduling between priorities. That is, if a lower-priority thread is running when a higher-priority thread becomes able to run, the virtual machine will sooner or later (and probably sooner) pause the lower-priority thread to allow the higher-priority thread to run. The higher-priority thread preempts the lower-priority thread.

    The situation when multiple threads of the same priority are able to run is trickier. A preemptive thread scheduler will occasionally pause one of the threads to allow the next one in line to get some CPU time. However, a cooperative thread scheduler will not. It will wait for the running thread to explicitly give up control or come to a stopping point. If the running thread never gives up control and never comes to a stopping point and if no higher-priority threads preempt the running thread, all other threads will starve. This is a bad thing. It's important to make sure all your threads periodically pause themselves so that other threads have an opportunity to run.

    There are 10 ways a thread can pause in favor of other threads or indicate that it is ready to pause. These are:

    • It can block on I/O.

    • It can block on a synchronized object.

    • It can yield.

    • It can go to sleep.

    • It can join another thread.

    • It can wait on an object.

    • It can finish.

    • It can be preempted by a higher-priority thread.

    • It can be suspended.

    • It can stop.

    You should inspect every run( ) method you write to make sure that one of these conditions will occur with reasonable frequency. The last two possibilities are deprecated because they have the potential to leave objects in inconsistent states, so let's look at the other eight ways a thread can be a cooperative citizen of the virtual machine.

    5.5.2.1 Blocking

    Blocking occurs any time a thread has to stop and wait for a resource it doesn't have. The most common way a thread in a network program will voluntarily give up control of the CPU is by blocking on I/O. Since CPUs are much faster than networks and disks, a network program will often block while waiting for data to arrive from the network or be sent out to the network. Even though it may block for only a few milliseconds, this is enough time for other threads to do significant work.

    Threads can also block when they enter a synchronized method or block. If the thread does not already possess the lock for the object being synchronized on and some other thread does possess that lock, the thread will pause until the lock is released. If the lock is never released, the thread is permanently stopped.

    Neither blocking on I/O nor blocking on a lock will release any locks the thread already possesses. For I/O blocks, this is not such a big deal, since eventually the I/O will either unblock and the thread will continue or an IOException will be thrown and the thread will then exit the synchronized block or method and release its locks. However, a thread blocking on a lock that it doesn't possess will never give up its own locks. If one thread is waiting for a lock that a second thread owns and the second thread is waiting for a lock that the first thread owns, deadlock results.

      回復  更多評論
      
    # re: Java多線程sleep(),join(),interrupt(),wait(),notify() 2009-06-08 21:10 | Frank_Fang
    5.5.2.2 Yielding

    The second way for a thread to give up control is to explicitly yield. A thread does this by invoking the static Thread.yield() method:

    public static void yield( )

    This signals the virtual machine that it can run another thread if one is ready to run. Some virtual machines, particularly on real-time operating systems, may ignore this hint.

    Before yielding, a thread should make sure that it or its associated Runnable object is in a consistent state that can be used by other objects. Yielding does not release any locks the thread holds. Therefore, ideally, a thread should not be synchronized on anything when it yields. If the only other threads waiting to run when a thread yields are blocked because they need the synchronized resources that the yielding thread possesses, then the other threads won't be able to run. Instead, control will return to the only thread that can run, the one that just yielded, which pretty much defeats the purpose of yielding.

    Making a thread yield is quite simple in practice. If the thread's run( ) method simply consists of an infinite loop, just put a call to Thread.yield( ) at the end of the loop. For example:

    public void run( ) {
    while (true) {
    // Do the thread's work...
    Thread.yield( );
    }
    }

    This gives other threads of the same priority the opportunity to run.

    If each iteration of the loop takes a significant amount of time, you may want to intersperse more calls to Thread.yield() in the rest of the code. This precaution should have minimal effect in the event that yielding isn't necessary.

      回復  更多評論
      
    # re: Java多線程sleep(),join(),interrupt(),wait(),notify() 2009-06-08 21:11 | Frank_Fang
    5.5.2.3 Sleeping

    Sleeping is a more powerful form of yielding. Whereas yielding indicates only that a thread is willing to pause and let other equal-priority threads have a turn, a thread that goes to sleep will pause whether any other thread is ready to run or not. This gives an opportunity to run not only to other threads of the same priority but also to threads of lower priorities . However, a thread that goes to sleep does hold onto all the locks it's grabbed. Consequently, other threads that need the same locks will be blocked even if the CPU is available. Therefore, try to avoid having threads sleeping inside a synchronized method or block.

    Sometimes sleeping is useful even if you don't need to yield to other threads. Putting a thread to sleep for a specified period of time lets you write code that executes once every second, every minute, every 10 minutes, and so forth. For instance, if you wrote a network monitor program that retrieved a page from a web server every five minutes and emailed the webmaster if the server had crashed, you could implement it as a thread that slept for five minutes between retrievals.

    A thread goes to sleep by invoking one of two overloaded static Thread.sleep( ) methods. The first takes the number of milliseconds to sleep as an argument. The second takes both the number of milliseconds and the number of nanoseconds:

    public static void sleep(long milliseconds) throws InterruptedException
    public static void sleep(long milliseconds, int nanoseconds)
    throws  InterruptedException

    While most modern computer clocks have at least close-to-millisecond accuracy, nanosecond accuracy is rarer. There's no guarantee that you can actually time the sleep to within a nanosecond or even within a millisecond on any particular virtual machine. If the local hardware can't support that level of accuracy, the sleep time is simply rounded to the nearest value that can be measured. For example:

    public void run( ) {
    while (true) {
    if (!getPage("http://www.cafeaulait.org/")) {
    mailError("elharo@metalab.unc.edu");
    }
    try {
    Thread.sleep(300000); // 300,000 milliseconds == 5 minutes
    }
    catch (InterruptedException ex) {
    break;
    }
    }
    }

    The thread is not absolutely guaranteed to sleep as long as it wants to. On occasion, the thread may not be woken up until some time after its requested wake-up call, simply because the VM is busy doing other things. It is also possible that some other thread will do something to wake up the sleeping thread before its time. Generally, this is accomplished by invoking the sleeping thread's interrupt( ) method.

    public void interrupt( )

    This is one of those cases where the distinction between the thread and the Thread object is important. Just because the thread is sleeping doesn't mean that other threads that are awake can't work with the corresponding Thread object through its methods and fields. In particular, another thread can invoke the sleeping Thread object's interrupt( ) method, which the sleeping thread experiences as an InterruptedException. From that point forward, the thread is awake and executes as normal, at least until it goes to sleep again. In the previous example, an InterruptedException is used to terminate a thread that would otherwise run forever. When the InterruptedException is thrown, the infinite loop is broken, the run( ) method finishes, and the thread dies. The user interface thread can invoke this thread's interrupt( ) method when the user selects Exit from a menu or otherwise indicates that he wants the program to quit.

      回復  更多評論
      
    # re: Java多線程sleep(),join(),interrupt(),wait(),notify() 2009-06-08 21:11 | Frank_Fang
    5.5.2.4 Joining threads

    It's not uncommon for one thread to need the result of another thread. For example, a web browser loading an HTML page in one thread might spawn a separate thread to retrieve every image embedded in the page. If the IMG elements don't have HEIGHT and WIDTH attributes, the main thread might have to wait for all the images to load before it can finish by displaying the page. Java provides three join( ) methods to allow one thread to wait for another thread to finish before continuing. These are:

    public final void join( ) throws InterruptedException
    public final void join(long milliseconds) throws InterruptedException
    public final void join(long milliseconds, int nanoseconds)
    throws InterruptedException

    The first variant waits indefinitely for the joined thread to finish. The second two variants wait for the specified amount of time, after which they continue even if the joined thread has not finished. As with the sleep() method, nanosecond accuracy is not guaranteed.

    The joining thread (that is, the one that invokes the join() method) waits for the joined thread (that is, the one whose join( ) method is invoked) to finish. For instance, consider this code fragment. We want to find the minimum, maximum, and median of a random array of doubles. It's quicker to do this with a sorted array. We spawn a new thread to sort the array, then join to that thread to await its results. Only when it's done do we read out the desired values.

    double[] array = new double[10000];                         // 1
    for (int i = 0; i < array.length; i++) {                  // 2
    array[i] = Math.random( );                                // 3
    }                                                           // 4
    SortThread t = new SortThread(array);                       // 5
    t.start( );                                                 // 6
    try {                                                       // 7
    t.join( );                                                // 8
    System.out.println("Minimum: " + array[0]);               // 9
    System.out.println("Median: " + array[array.length/2]);   // 10
    System.out.println("Maximum: " + array[array.length-1]);  // 11
    }                                                           // 12
    catch (InterruptedException ex) {                           // 13
    }                                                           // 14
    

    First lines 1 through 4 execute, filling the array with random numbers. Then line 5 creates a new SortThread. Line 6 starts the thread that will sort the array. Before we can find the minimum, median, and maximum of the array, we need to wait for the sorting thread to finish. Therefore, line 8 joins the current thread to the sorting thread. At this point, the thread executing these lines of code stops in its tracks. It waits for the sorting thread to finish running. The minimum, median, and maximum are not retrieved in lines 9 through 10 until the sorting thread has finished running and died. Notice that at no point is there a reference to the thread that pauses. It's not the Thread object on which the join() method is invoked; it's not passed as an argument to that method. It exists implicitly only as the current thread. If this is within the normal flow of control of the main( ) method of the program, there may not be any Thread variable anywhere that points to this thread.

    A thread that's joined to another thread can be interrupted just like a sleeping thread if some other thread invokes its interrupt( ) method. The thread experiences this invocation as an InterruptedException. From that point forward, it executes as normal, starting from the catch block that caught the exception. In the preceding example, if the thread is interrupted, it skips over the calculation of the minimum, median, and maximum because they won't be available if the sorting thread was interrupted before it could finish.

      回復  更多評論
      
    # re: Java多線程sleep(),join(),interrupt(),wait(),notify() 2009-06-08 21:15 | Frank_Fang
    5.5.2.5 Waiting on an object

    A thread can wait on an object it has locked. While waiting, it releases the lock on the object and pauses until it is notified by some other thread. Another thread changes the object in some way, notifies the thread waiting on that object, and then continues. This differs from joining in that neither the waiting nor the notifying thread has to finish before the other thread can continue. Waiting is used to pause execution until an object or resource reaches a certain state. Joining is used to pause execution until a thread finishes.

    Waiting on an object is one of the lesser-known ways a thread can pause. That's because it doesn't involve any methods in the Thread class. Instead, to wait on a particular object, the thread that wants to pause must first obtain the lock on the object using synchronized and then invoke one of the object's three overloaded wait( ) methods:

    public final void wait( ) throws InterruptedException 
    public final void wait(long milliseconds) throws InterruptedException
    public final void wait(long milliseconds, int nanoseconds)
    throws InterruptedException

    These methods are not in the Thread class; rather, they are in the java.lang.Object class. Consequently, they can be invoked on any object of any class. When one of these methods is invoked, the thread that invoked it releases the lock on the object it's waiting on (though not any locks it possesses on other objects) and goes to sleep. It remains asleep until one of three things happens:

    • The timeout expires.

    • The thread is interrupted.

    • The object is notified.

    The timeout is the same as for the sleep( ) and join( ) methods; that is, the thread wakes up after the specified amount of time has passed (within the limits of the local hardware clock accuracy). When the timeout expires, execution of the thread resumes with the statement immediately following the invocation of wait(). However, if the thread can't immediately regain the lock on the object it was waiting on, it may still be blocked for some time.

    Interruption works the same way as sleep( ) and join( ): some other thread invokes the thread's interrupt( ) method. This causes an InterruptedException, and execution resumes in the catch block that catches the exception. The thread regains the lock on the object it was waiting on before the exception is thrown, however, so the thread may still be blocked for some time after the interrupt( ) method is invoked.

    The third possibility, notification, is new. Notification occurs when some other thread invokes the notify( ) or notifyAll( ) method on the object on which the thread is waiting. Both of these methods are in the java.lang.Object class:

    public final void notify( )
    public final void notifyAll( )
    These must be invoked on the object the thread was waiting on, not generally on the Thread itself. Before notifying an object, a thread must first obtain the lock on the object using a synchronized method or block. The notify( ) method selects one thread more or less at random from the list of threads waiting on the object and wakes it up. The notifyAll() method wakes up every thread waiting on the given object.
     
    Once a waiting thread is notified, it attempts to regain the lock of the object it was waiting on. If it succeeds, execution resumes with the statement immediately following the invocation of wait(). If it fails, it blocks on the object until its lock becomes available; then execution resumes with the statement immediately following the invocation of wait( ).
      回復  更多評論
      
    主站蜘蛛池模板: 亚洲成色www久久网站夜月| 亚洲午夜精品在线| 久久青草免费91观看| 亚洲伊人久久大香线蕉影院| 高清国语自产拍免费视频国产| a级毛片免费观看在线| 亚洲资源在线观看| 日韩成人免费在线| a毛片免费观看完整| 亚洲精品456人成在线| 国产亚洲大尺度无码无码专线 | 一级毛片免费毛片一级毛片免费 | 青青视频观看免费99| 国产av无码专区亚洲av毛片搜| 国产AV无码专区亚洲AVJULIA| 动漫黄网站免费永久在线观看| 日韩毛片在线免费观看| 亚洲精品456在线播放| 亚洲国产成人久久综合一区77 | 青青青国产在线观看免费网站 | 一边摸一边桶一边脱免费视频| 亚洲综合一区二区国产精品| 国产一区二区三区在线免费| 99视频有精品视频免费观看| 黄色免费在线网址| 激情内射亚洲一区二区三区爱妻 | 狼色精品人妻在线视频免费| 亚洲最大免费视频网| 亚洲中文久久精品无码| 国产在线a不卡免费视频| 中文字幕成人免费视频| WWW国产成人免费观看视频| 亚洲精品无码久久久久A片苍井空| 亚洲AV成人一区二区三区AV| 免费在线黄色网址| 18禁超污无遮挡无码免费网站国产| 国产日韩一区二区三免费高清| 国产亚洲精品国产福利在线观看 | 亚洲第一AAAAA片| 亚洲视频在线免费| 国产又黄又爽又猛的免费视频播放 |