首先区分一下概念,什么是线程同步,什么是线程通信。
线程同步是指
线程通信
线程通信有两种机制,一是用锁实例的wait()/notify()机制,二是用Condition的await()/signal()机制。
wait()/notify()机制又称为等待/通知机制,指的是,在线程A中调用了锁对象的wait()方法后,线程A释放锁并进入锁对象的等待队列(变为waiting 状态),在另一个线程B调用了锁对象的notify()或者notifyAll()方法,线程A收到通知,待线程B释放锁后,再去竞争锁,如果获取到锁,则从wait()方法返回,继续执行后续操作。
wait()方法调用线程必须拥有这个锁对象的监视器,换句话说,调用线程必须先获取到这个锁,否则会抛IllegalMonitorStateException异常。调用wait()方法后,调用线程释放掉锁,并且等待,直到另一个线程中调用了同一个锁对象的notify()方法或者notifyAll()方法。之后调用wait()方法的线程会等待,直到重新获取到锁,然后再执行剩余的代码。
notify()方法调用线程也必须先获得获取到这个锁,否则也会抛IllegalMonitorStateException异常。notify()方法会唤醒在这个锁上等待的某一个线程,被唤醒的线程会在调用notify()方法的线程释放锁之后,和其他线程一样去竞争锁,获取到锁的机会和其他线程是均等的。notifyAll()方法会唤醒在这个锁上等待的所有线程。注意,notify()/notifyAll()方法不会释放锁,等同步代码块或者同步方法执行完,或是主动调用Lock实例的unlock()方法,才会释放锁。
Condition的await()/signal()机制,主要用到Condition接口中的方法
await:
void await() throws InterruptedException:
调用者Condition实例对应的锁会被释放,调用者线程会等待,直到以下情况发生:
在其他线程中调用了同一个Condition实例的signal()方法,且上述await线程刚好被选中通知唤醒
在其他线程中调用了同一个Condition实例的signalAll()方法
在其他线程中调用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线程必须要重新获取到对应的锁。换句话说,返回的话一定已经获取到了锁。
boolean await(long time, TimeUnit unit) throws InterruptedException:
调用者线程等待,直到被通知、被中断或者到了指定的时间。到了指定时间会返回false,否则会返回true。
await()相关的三个方法:
long awaitNanos(long nanosTimeout) throws InterruptedException;
void awaitUninterruptibly();
boolean awaitUntil(Date deadline) throws InterruptedException;
signal:
signal():唤醒一个在这个Condition实例上等待的线程。执行这个方法的线程必须已经获取到了Condition实例对应的锁,否则会抛IlleagleMonitorStateException。
signalAll():唤醒在这个Condition实例上等待的全部线程。