05_线程间通信

【简述】

为了支持多线程之间的协作,JDK提供了两个重要的线程方法:通知notify()、等待wait()。

任何对象都可以调用这两个方法,因为他们在Object类中。

 

【wait方法】

当一个对象调用了wait方法之后,当前线程就会在这个对象上等待。比如,线程A中,调用了obj.wait()方法,那么线程A就会停止执行,而转为等待状态,同时当前线程释放持有的锁,线程A会一直等待到其它线程调用了obj.notify()方法通知到自己位置。obj对象成为了多个线程之间通信的手段。

 

【wait方法和notify方法工作细节】

     如果一个线程调用了object.wait(),那么他就会进入object对象的等待队列。这个等待队列中,可能会有多个线程,因为系统运行多个线程同时会等待某一对象,当object.notify()方法被调用后,它就会从这个等待队列中随机选择一个线程(和队列中的顺序无关),并将其唤醒。

    notifyAll()可以唤醒所有的等待线程,而不是随机选择一个。

注意:object.wait()方法不可以随意调用,必须包含在对应的synchronizd语句中。无论是wait()还是notify()方法都需要获得目标对象的一个监听器。

 

【使用wait和notify的注意点】

1.wait和notify必须配合synchronized关键字使用

2.wait方法释放锁,而notify不会释放锁

 

【例子】

 

package com.part1.sync005;

import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleWN {
    final static Object object = new Object();
    
    public static class T1 extends Thread{
        @Override
        public void run() {
            synchronized(object){
                System.out.println(getNowTime()+" T1 start!!!");
                try{
                    Thread.sleep(1000);
                    System.out.println(getNowTime()+" T1 wait for Object... ");
                    object.wait();     //T1释放锁,等待其他线程来唤醒
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                System.out.println(getNowTime()+" T1 end...");
            }
        }
    }
    
    public static class T2 extends Thread{
        @Override
        public void run() {
            synchronized(object){
                try {
                    System.out.println(getNowTime()+" T2 start !!! notify one Thread !!!");
                    object.notify();  //从object等待队列中随机唤醒一个等待线程,此时只有T1在等待,故唤醒T1
                    System.out.println(getNowTime()+" T2 end...");  //虽然T2唤醒了T1线程,但是T2此时依然持有锁,所以T1处于阻塞状态
                    Thread.sleep(2000);   //T2执行结束,释放锁,T1方可去获取锁
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    public static void main(String[] args) {
        Thread t1 = new T1();
        Thread t2 = new T2();
        
        t1.start();
        t2.start();
    }
    
    public static String getNowTime(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(new Date());
    }
}

【运行结果】

 

posted @ 2016-09-24 12:35  HigginCui  阅读(288)  评论(0编辑  收藏  举报