在JDK1.5之前,多线程并发一般用synchronized关键字来实现。1.5之后,在java.util.concurrent包提供了更强大的支持。
synchronized 方法或语句的使用提供了对与每个对象相关的隐式监视器锁定的访问,但却强制所有锁定获取和释放均要出现在一个块结构中:
当获取了多个锁定时,它们必须以相反的顺序释放,且必须在与所有锁定被获取时相同的词法范围内释放所有锁定。
Lock 接口的实现允许锁定在不同的作用范围内获取和释放,并允许以任何顺序获取和释放多个锁定,从而支持使用这种技术。
随着灵活性的增加,也带来了更多的责任。锁定和取消锁定出现在不同作用范围中时,必须谨慎地确保保持锁定时所执行的所有代码用 try-finally 或 try-catch 加以保护,以确保在必要时释放锁定。
Lock interface
三种形式的锁定获取(可中断、不可中断和定时)在其性能特征、排序保证或其他实现质量上可能会有所不同。
一个非块结构的获取锁定尝试 (tryLock())、
一个获取可中断锁定的尝试 (lockInterruptibly())
一个获取超时失效锁定的尝试 (tryLock(long, TimeUnit))
void lock() 如果无法获取锁,线程休眠
void lockInterruptibly() throws InterruptedException, 如果无法获取锁,线程休眠,但同时可以被中断
boolean tryLock() 无论是否能获得锁,都立即返回,只是返回值不同。只有返回true的情况下才在try-finally的finally中unlock()锁,否则不必要
boolean tryLock(long, TimeUnit) throws InterruptedException, 与tryLock()的区别是如果不能立即获取锁,可以等待一段时间进行休眠,在此期间可以被中断。
void unlock() 释放锁
Condition newCondition() 返回绑定到此 Lock 实例的新 Condition 实例。
Before waiting on the condition the lock must be held by the current thread. A call to Condition.await() will atomically release the lock before waiting and re-acquire the lock before the wait returns.
可以用来实现信号量:
class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
synchronized 方法或语句的使用提供了对与每个对象相关的隐式监视器锁定的访问,但却强制所有锁定获取和释放均要出现在一个块结构中:
当获取了多个锁定时,它们必须以相反的顺序释放,且必须在与所有锁定被获取时相同的词法范围内释放所有锁定。
Lock 接口的实现允许锁定在不同的作用范围内获取和释放,并允许以任何顺序获取和释放多个锁定,从而支持使用这种技术。
随着灵活性的增加,也带来了更多的责任。锁定和取消锁定出现在不同作用范围中时,必须谨慎地确保保持锁定时所执行的所有代码用 try-finally 或 try-catch 加以保护,以确保在必要时释放锁定。
Lock interface
三种形式的锁定获取(可中断、不可中断和定时)在其性能特征、排序保证或其他实现质量上可能会有所不同。
一个非块结构的获取锁定尝试 (tryLock())、
一个获取可中断锁定的尝试 (lockInterruptibly())
一个获取超时失效锁定的尝试 (tryLock(long, TimeUnit))
void lock() 如果无法获取锁,线程休眠
void lockInterruptibly() throws InterruptedException, 如果无法获取锁,线程休眠,但同时可以被中断
boolean tryLock() 无论是否能获得锁,都立即返回,只是返回值不同。只有返回true的情况下才在try-finally的finally中unlock()锁,否则不必要
boolean tryLock(long, TimeUnit) throws InterruptedException, 与tryLock()的区别是如果不能立即获取锁,可以等待一段时间进行休眠,在此期间可以被中断。
void unlock() 释放锁
Condition newCondition() 返回绑定到此 Lock 实例的新 Condition 实例。
Before waiting on the condition the lock must be held by the current thread. A call to Condition.await() will atomically release the lock before waiting and re-acquire the lock before the wait returns.
可以用来实现信号量:
class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}