多线程基础知识第二篇:线程同步和线程通信

首先区分一下概念,什么是线程同步,什么是线程通信。

线程同步是指

同步监视器(同步代码块、同步方法) synchronized

锁 Lock

线程通信

线程通信有两种机制,一是用监视器锁的wait/notify机制,二是用Condition的await/signal机制。

wait/notify是配合监视器锁使用的,await/signal是配合Lock使用的。

wait/notify机制又称为等待/通知机制,指的是,在线程A中调用了锁对象的wait()方法后,线程A立即释放锁并进入监视器锁对象的等待队列(变为waiting状态),在另一个线程B调用了监视器锁对象的notify()或者notifyAll()方法,线程A收到通知,待线程B释放监视器锁后,再去竞争监视器锁,如果获取到监视器锁,则从wait()方法返回,执行后续操作。

wait()方法调用线程必须先获取到这个监视器锁之后才能调用wait()方法,否则会抛IllegalMonitorStateException异常。调用wait()方法后,调用线程释放掉监视器锁,并且等待,直到另一个线程中调用了同一个监视器锁对象的notify()方法或者notifyAll()方法。

notify()方法调用线程也必须先获得获取到这个监视器锁,否则也会抛IllegalMonitorStateException异常。notify()方法会唤醒在这个监视器锁上等待的某一个线程,被唤醒的线程会在调用notify()方法的线程释放监视器锁之后,和其他线程一样去竞争监视器锁,获取到监视器锁的机会和其他线程是均等的。notifyAll()方法会唤醒在这个监视器锁上等待的所有线程。注意,notify()/notifyAll()方法不会释放监视器锁,等同步代码块或者同步方法执行完,才会释放监视器锁。

释放监视器锁的时机有:

1、线程执行完

2、线程抛异常

3、线程调用监视器锁的wait()方法

Condition的await/signal机制,主要用到Condition接口中的方法

await:

void await() throws InterruptedException:

调用者Condition实例对应的锁会被释放,调用者线程会等待,直到以下情况发生:

1、在其他线程中调用了同一个Condition实例的signal()方法,且上述await线程刚好被选中通知唤醒

2、在其他线程中调用了同一个Condition实例的signalAll()方法

3、在其他线程中调用await线程的interrupt()实例方法中断了该线程

In all cases, before this method can return the current thread must re-acquire the lock associated with this condition. When the thread returns it is guaranteed to hold this lock.

在await()方法返回之前,await线程必须要重新获取到对应的锁。换句话说,返回的话一定已经获取到了锁。完成业务后,不要忘了调用锁实例的unlock方法释放掉锁。

signal:

signal():唤醒一个在这个Condition实例上等待的线程。

signalAll():唤醒在这个Condition实例上等待的全部线程。

Condition实例的await和signal方法,都必须在调用线程获得了该Condition实例对应的锁之后再调用,否则也会抛IlleagleMonitorStateException。

Condition实例不是new出来的,而是通过调用Lock实例的newCondition()方法获得的。Lock接口的实现类有ReentrantLock、ReentrantReadWriteLock.WriteLock、ReentrantReadWriteLock.ReadLock。而可重入读写锁的读锁不支持Condition,仅写锁支持Condition。

posted on 2015-07-15 17:00  koushr  阅读(391)  评论(0编辑  收藏  举报

导航