lock接口
Lock lock = ...;
lock.lock();
try{//处理任务
}catch(Exception ex){
}finally{lock.unlock(); //释放锁
}
经常这样使用
Lock lock = ...;
if(lock.tryLock()) {try{//处理任务}catch(Exception ex){}finally{lock.unlock(); //释放锁}
}else {//如果不能获取锁,则直接做其他事情
}
lock()方法
ReentrantLock
是Lock
接口的一个实现类,意思是“可重入锁”,接下来我们通过一个例子来学习lock()
方法的正确使用方式。
因为Lock
是一个接口所以我们在编程时一般会使用它的实现类,ReentrantLock
是Lock
接口的一个实现类,意思是“可重入锁”,接下来我们通过一个例子来学习lock()
方法的正确使用方式。
示例1:
public class Test {private ArrayList<Integer> arrayList = new ArrayList<Integer>();public static void main(String[] args) {final Test test = new Test();new Thread(){public void run() {test.insert(Thread.currentThread());};}.start();new Thread(){public void run() {test.insert(Thread.currentThread());};}.start();} public void insert(Thread thread) {Lock lock = new ReentrantLock(); //注意这个地方lock.lock();try {System.out.println(thread.getName()+"得到了锁");for(int i=0;i<5;i++) {arrayList.add(i);}} catch (Exception e) {// TODO: handle exception}finally {System.out.println(thread.getName()+"释放了锁");lock.unlock();}}
}
输出:
Thread-1得到了锁` `Thread-0得到了锁` `Thread-0释放了锁` `Thread-1释放了锁
结果可能出乎你的意料,不对呀,按道理应该是一个线程得到锁其他线程不能获取锁了的啊,为什么会这样呢?是因为insert()
方法中lock
变量是一个局部变量。THread-0
和Thread-1
获取到的是不同的锁,这样不会造成线程的等待。
那怎么才能利用lock()
实现同步呢?相信你已经想到了,只要将Lock定义成全局变量就可以了。
public class Test {private ArrayList<Integer> arrayList = new ArrayList<Integer>();private Lock lock = new ReentrantLock(); //注意这个地方public static void main(String[] args) {final Test test = new Test();new Thread(){public void run() {test.insert(Thread.currentThread());};}.start();new Thread(){public void run() {test.insert(Thread.currentThread());};}.start();} public void insert(Thread thread) {lock.lock();try {System.out.println(thread.getName()+"得到了锁");for(int i=0;i<5;i++) {arrayList.add(i);}} catch (Exception e) {// TODO: handle exception}finally {System.out.println(thread.getName()+"释放了锁");lock.unlock();}}
}
结果:
Thread-0得到了锁` `Thread-0释放了锁` `Thread-1得到了锁` `Thread-1释放了锁
这样就是我们预期的结果了。
很多时候我们为了提高程序的效率不希望线程为了等待锁而一直阻塞,这个时候可以使用tryLock()
可以达到目的。
示例,将之前的insert()
方法修改成tryLock()
实现:
public void insert(Thread thread) {if(lock.tryLock()) {try {System.out.println(thread.getName()+"得到了锁");for(int i=0;i<5;i++) {arrayList.add(i);}} catch (Exception e) {// TODO: handle exception}finally {System.out.println(thread.getName()+"释放了锁");lock.unlock();}} else {System.out.println(thread.getName()+"获取锁失败");}
}
输出:
Thread-0得到了锁` `Thread-1获取锁失败` `Thread-0释放了锁