您的位置:首页 > 其它

线程之间的通信

2018-02-24 16:30 211 查看
        有的时候我们需要来控制线程之间的执行顺序,而线程之间的通信就借助于变量之间的关系,比如在变量是什么状态下让什么线程来执行。
        当我们在使用同步锁的时候可以使用object的wait(),notify(),notifyAll()来控制线程是否等待,是否被唤醒。

        下面使用一个简单的购票的例子来说明线程之间的通信:

        购票规则是只要是有票,生产票的线程就等待,直到没有票的时候被唤醒。消费票的线程相反,如果没有票就等待,直到有票之后被唤醒。

下面使用synchronized同步锁来演示:












从结果看出来我们实现了线程之间的通讯,只要是有票生产者就会被阻塞住,为什么需要使用synchronized关键字呢?
是因为我们在线程通信时,唤醒的线程是获得了对象同步锁的线程。因此我们需要使用synchronized关键字。
除了使用synchronized关键字我们还可以使用reentrantlock(可重入锁)来保证线程安全,使用condition对象来保证线程通信
方法有await();signal();signalAll().
在使用condition的时候需要先给reentrantlock对象加锁
伪代码如下
ReentrantLock lock = new ReentrantLock();

Condition condition = lock.newCondition();
代码块
try{
//加锁
lock.lock()
//需要进行线程通信的地方
condition.await();
}finally{
//一定需要记住关闭锁,一般写在finally中,因为有可能异常发生,导致锁不能关闭使得其他的线程处于阻塞中
    lock.unlock()

}
除此之外我们还可以使用阻塞队列,阻塞队列其实就是queue的一个实现类,多了一个put和take方法,这两个方法的内部都是加了可重入锁的,如下图(jdk源码):



可以看到如果在操作队列的时候队列内部为空则当前线程会被阻塞住,同理put。其他的方法会加上同步锁但是不会使得线程阻塞 如下图:



        除此之外还有可重入读写锁,在获得读锁的线程上可以再加上写锁,读锁还可以被共享,但是如果之前加上了写锁,就不可以共享锁,且读写锁之间互斥,写写锁之间也是互斥的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: