Java学习笔记81. 线程间的通信 —— wait( ),notify( ),和 notifyAll( )

线程之间是可以通信的,线程间通信的方法有wait,notify和notifyAll。这3个方法是定义在Object类里面的,一切类和对象都天然地可以使用者3个方法。但是使用这些方法的前提是在synchronized修饰的语句块下。

wait的意义是中止当前线程,释放锁,并等待;

notify的意义是结束第一个开始等待中的线程,使其处于就绪状态,但是不释放锁。

notifyAll的意义是结束所有正在等待中的线程,全部放入排队获得锁的线程池里面。

用一个例子来说明一下:

import java.util.*;        引入列表类
public class waitandnotify{
    private volatile static List list = new ArrayList();    //定义并创建一个列表类对象list

    public void add(){    //定义waitandnotify的方法add,这个方法是往对象list里加入一个字符串元素
        list.add("Hello");
    }
    public int size(){    //定义waitandnotify的方法size,这个方法是把对象的size返回
        return list.size();
    }
    public static void main(String[] args){    //main方法

    final waitandnotify wt = new waitandnotify();    //创建一个本类的对象
    final Object lock = new Object();    //定义并创建一个锁的对象
    Thread t1 = new Thread(new Runnable(){    //创建一个线程实例t1
        public void run(){    //覆盖t1的run方法
            try{
                synchronized(lock){    //为run方法的代码块加锁
                    for(int i=0;i<10;i++){
                        wt.add();    //调用本类的add方法
                        /*输出当前线程的名称*/
                        System.out.println("current thread is "+Thread.currentThread().getName()+" one element added");
                        Thread.sleep(500);    /*中止当前线程500ms,让第二线程执行*/
                        if(wt.size()==5){    //如果列表list里的元素有5个了,就输出信息,并notify通知wait的线程
                            System.out.println("message sent");
                            lock.notify();    //通知wait的排队中的第一个线程
                        }
                    }
                }
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    },"t1");    //线程命名为t1

    Thread t2 = new Thread(new Runnable(){    //创建第2个线程实例
        public void run(){        //覆盖run方法
            synchronized(lock){    //给run方法加锁,两个run方法是不同的,但是用的是同一把锁,锁不释放,下面的代码就没法执行
                if(wt.size()!=5){    //得到锁之后,当list的元素不是5个时,就执行下面
                    try{
                        lock.wait();    //当list里的元素不等于5时,释放锁,并等待
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                }
               //输出当前线程的名字
                System.out.println("Current thread is "+Thread.currentThread().getName()+" message received");
                throw new RuntimeException();    //抛一个异常出来
            }
        }

    },"t2");
    t2.start();    //先启动t2,先判断线程t2要不要wait
    t1.start();

}
}

编译执行,结果如下

由结果可见,线程t2先获得锁,但是不符合条件,释放锁,线程t1得到锁,执行到第5行时,notify线程t1,但是并没有释放锁。一直到线程t1的语句执行完,才释放锁。随后线程t2得到锁,开始执行程序,最后抛一个异常出来。

所以,通过一个例子就能知道,wait和notify的运作机制。关于线程的通信,我相信还有很多很复杂的层面,等我深入学习后,再结合实际的例子来总结。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值