在Java中Synchronized的用法中,我们介绍了通过Synchronized
实现线程同步的机制。除了通过Synchronized
实现线程同步之外,我们还可以通过同步锁(java.util.concurrent.locks.Lock)实现线程同步。
看下下面代码
package com.company.threadpackage;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Apple implements Runnable {
private int num = 50;
private final Lock lock = new ReentrantLock();
@Override
public void run() {
while (num > 0) {
lock.lock();
try {
if (num > 0) {
System.out.println(Thread.currentThread().getName() + " 吃了编号为 " + num-- + " 的苹果");
}
}finally {
lock.unlock();
}
}
}
}
调用
Apple apple = new Apple();
for(int i=0;i<1000;i++){
new Thread(apple,"apple"+i).start();
}
查看控制台,可以看到,num
始终是在顺序减少。
- Lock 接口的实现允许锁在不同的作用范围内获取和释放,并允许以任何顺序获取和释放多个锁。
- 常用的实现类ReentrantLock(可重入锁):java.util.concurrent.locks 包中,通常建议使用 finally 块来确保在必要时释放锁ReentrantLock 是可重入锁:当前持有该锁的线程能够多次获取该锁,无需等待(可以在递归算法中使用锁)
[typing]Lock 和 synchronized 的选择[/typing]
Lock
是一个接口,而synchronized
是Java中的关键字,synchronized
是内置的语言实现synchronized
在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock
在发生异常时,如果没有主动通过unLock
去释放锁,则很可能造成死锁现象,因此使用Lock
时需要在finally
块中释放锁Lock
可以让等待锁的线程响应中断,而synchronized
却不行,使用synchronized
时,等待的线程会直等待下去,不能够响应中断- 通过
Lock
可以知道有没有成功获取锁,而synchronized
却无法办到 Lock
可以提高多个线程进行读操作的效率- 在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竟争),此时
Lock
的性能要远远优于synchronized
。所以说,在具体使用时要根据适当情况选择
评论 (0)