线程间的通信

    技术2022-05-19  23

    平时的java程序中很少用到两个线程间的通信,但当编写网络程序时,就会常常用到了。

    一个线程包含的方法有:

    yield() 不释放自己已经占用的锁。

    sleep() 不多说。 可以被interrupt。

     

    join() 线程A等待线程B执行完成。

     

    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 InterruptedExceptionpublic final void join(long milliseconds) throws InterruptedExceptionpublic final void join(long milliseconds, int nanoseconds) throws InterruptedException

     

    具体是谁等待谁完成,看下面代码:

    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 }

     

    主线程要找到数组的最大,最小,和中间的数, 但它要等SortThread执行完成后才能用它的结果,所以在主线程中 t.join() 表明,主线程等待,直到 t 线程完成,然后再输出结果。

     

    wait() 详解

     

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

     

    wait()方法的调用不是由线程触发,而是由共享的资源对象触发。当共享的资源触发wait() 时,它首先释放掉本线程所占用的锁,然后进入sleep状态。直到共享资源调用自己的 notify() (随即唤醒一个线程) 或notifyAll() ,则刚才 sleep 的线程被唤醒,并开始争夺锁。 所以在调用 wait() 前,一般是已经获得 lock了!


    最新回复(0)