类别
|
synchronized
|
Lock
|
存在层次
|
Java的关键字,在jvm层面上
|
是一个类 java.util.concurrent.locks
|
锁的释放
|
1、以获取锁的线程执行完同步代码,释放锁 2、线程执行发生异常,jvm会让线程释放锁
|
一般用在try()catch{}中然后在finally中必须释放锁,不然容易造成线程死锁
|
锁的获取
|
假设A线程获得锁,B线程等待。如果A线程阻塞,B线程会一直等待
|
分情况而定,Lock有多个锁获取的方式
一般如果用Lock.lock()锁那么如果一个线程占用另外一个线程也必须在一直等待当前线程释放锁之后才能执行
但是如果使用的是tyLock()锁的话一个线程占用锁那么其他线程则不用等待可以先去做其他事情或者返回
|
锁状态
|
无法判断
|
可以判断
tryLock()方法是有返回值的,它表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false,也就说这个方法无论如何都会立即返回。在拿不到锁时不会一直在那等待。
tryLock(long time, TimeUnit unit)方法和tryLock()方法是类似的,只不过区别在于这个方法在拿不到锁时会等待一定的时间,在时间期限之内如果还拿不到锁,就返回false。如果如果一开始拿到锁或者在等待期间内拿到了锁,则返回true。
|
锁类型
|
可重入 不可中断 非公平
|
可重入 可判断 可公平(两者皆可)
|
性能
|
少量同步(并发量小的时候效率还可以)
|
大量同步(并发量大时效率也可以,在并发量小的时候与
synchronized区别不大
)
|
lock.lock();
try{
//处理任务
中间加锁执行的代码
}catch(Exception ex){
捕获异常
}finally{
lock.unlock(); //释放锁
}
boolean tryLock = lock.tryLock();
或者boolean tryLock = lock.tryLock(long time, TimeUnit.MILLISECONDS);
第一个参数是时间,第二个参数是时间单位(秒或毫秒,纳秒等等)
if(tryLock ) {
try{
//处理任务
}catch(Exception ex){
捕获异常
}finally{
lock.unlock(); //释放锁
}
}else {
//如果不能获取锁,则直接做其他事情
}
public class Test {
private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
public static void main(String[] args) {
final Test test = new Test();
new Thread(){
public void run() {
test.get(Thread.currentThread());
};
}.start();
new Thread(){
public void run() {
test.get(Thread.currentThread());
};
}.start();
}
public void get(Thread thread) {
rwl.readLock().lock();
try {
long start = System.currentTimeMillis();
while(System.currentTimeMillis() - start <= 1) {
System.out.println(thread.getName()+"正在进行读操作");
}
System.out.println(thread.getName()+"读操作完毕");
} finally {
rwl.readLock().unlock();
}
}
}