Lock接口中的几个方法讨论
来源:互联网 发布:sql plus 登录 编辑:程序博客网 时间:2024/05/27 19:26
显示锁Lock和ReentrantLock
Lock 是一个接口,提供了无条件的、可轮询的、定时的、可中断的锁获取操作,所有加锁和解锁的方法都是显示的。核心方法有lock()、unlock()、tryLock(),实现类有ReentrantLock、ReentrantReadWriteLock.ReadLock、ReentrantReadWriteLock.WriteLock
void lock()
拿不到lock就不罢休,不然线程就一直block,调用方法结束后,要是用unlock,否则会造成死锁
代码结构示例:
public void m(){ lock.lock(); try { } catch (Exception e) { // TODO: handle exception }finally{ lock.unlock(); } }
boolean tryLock()
马上返回,拿到lock就返回true,不然返回false;通常对于那种不必获取锁的操作可能有用,注意必须拿到锁的方法才可调用unlock()方法
import java.util.concurrent.locks.ReentrantLock;public class LockTest { ReentrantLock lock = new ReentrantLock(); public void tryLockTest(){ try { boolean getLock = lock.tryLock(); if(getLock){ System.out.println("Thead----"+Thread.currentThread().getName()+"---get lock---"); Thread.sleep(10); lock.unlock();//必须拿到锁的线程才可调用此方法,否则抛异常 }else{ System.out.println("Thead----"+Thread.currentThread().getName()+"---not get lock---"); Thread.sleep(10); } }catch(Exception e){ System.out.println(Thread.currentThread().getName()+"异常"); e.printStackTrace(); } }}
运行结果:
由结果可以看出,只有第一个线程获取到锁。
boolean tryLock(long ParamLong,TimeUnit ParamTimeUnit) throws InterruptedException
带时间限制的tryLock(),拿不到lock,就等一段时间,超时返回false
图中画红框部分是经修改的代码,修改后的执行结果如下
当线程没有拿到lock,要等一会,超时后仍没有拿到,才会返回false
void lockInterruptibly() throws InterruptedException
优先考虑响应中断,而不是响应锁定的普通获取,当外部线程被Interrupted,则当线程调用lockInterruptibly时进入catch方法中,若外部线程没有被打断,则与功能与调用lock方法一致
代码进行如下修改
子方法中调用lockInterruptibly()
主方法中,将一些线程打断
下面我们看一下执行结果
Lock与synchronized比较
1、lock使用起来更加灵活,但是必须有释放锁的动作配合
2、lock适用于代码块,而synchronized是对象之间的互斥锁
注意以下两种方式的区别
第一种方式:两个方法之间的锁是独立的
public class MainT { /** * @param args */ public static void main(String[] args) { final LockTest lt = new LockTest(); //final LockTest lt2 = new LockTest(); // TODO Auto-generated method stub for(int i=0;i<2;i++){ Thread t1=new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub lt.get(); } }); t1.start(); } for(int i=0;i<2;i++){ Thread t1=new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub lt.put(); } }); t1.start(); } }}
import java.util.concurrent.locks.ReentrantLock;public class LockTest { public void get(){ ReentrantLock lock = new ReentrantLock(); try { lock.lock(); System.out.println(Thread.currentThread().getName()+"----get begin---"); Thread.sleep(1000);//模仿干活 System.out.println(Thread.currentThread().getName()+"----get end---"); lock.unlock(); } catch (Exception e) { // TODO: handle exception } } public void put(){ ReentrantLock lock = new ReentrantLock(); try { lock.lock(); System.out.println(Thread.currentThread().getName()+"----put begin---"); Thread.sleep(1000);//模仿干活 System.out.println(Thread.currentThread().getName()+"----put end---"); lock.unlock(); } catch (Exception e) { // TODO: handle exception } }}
每个调用此方法的锁都是独立的,没有起到锁的用途
第二种方式:两个方法之间使用相同的锁
/** * @param args */ public static void main(String[] args) { final LockTest lt = new LockTest(); // TODO Auto-generated method stub for(int i=0;i<2;i++){ Thread t1=new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub lt.get(); } }); t1.start(); } for(int i=0;i<2;i++){ Thread t1=new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub lt.put(); } }); t1.start(); } }}
import java.util.concurrent.locks.ReentrantLock;public class LockTest { ReentrantLock lock = new ReentrantLock(); public void get(){ try { lock.lock(); System.out.println(Thread.currentThread().getName()+"----get begin---"); Thread.sleep(1000);//模仿干活 System.out.println(Thread.currentThread().getName()+"----get end---"); lock.unlock(); } catch (Exception e) { // TODO: handle exception } } public void put(){ try { lock.lock(); System.out.println(Thread.currentThread().getName()+"----put begin---"); Thread.sleep(1000);//模仿干活 System.out.println(Thread.currentThread().getName()+"----put end---"); lock.unlock(); } catch (Exception e) { // TODO: handle exception } }}
两个线程调用方法使用的同一个锁,所以串行执行;结果如下图所示
- Lock接口中的几个方法讨论
- C#中的Lock方法
- Javascript中的Call方法讨论
- Javascript中的Call方法讨论
- Java中的锁-Lock接口解析
- Java 中的锁 -Lock 接口解析
- Hibernate中的几个核心接口
- 接口 Lock
- 接口 Lock
- Lock接口
- Lock接口
- 如何重写的 MFC 控件容器接口方法在 Visual C++ 中的几个默认行为(转)
- 如何重写的 MFC 控件容器接口方法,在 Visual c + + 中的几个默认行为
- 如何重写的 MFC 控件容器接口方法,在 Visual c + + 中的几个默认行为
- 关于接口中的方法
- Connection接口中的方法
- 接口中的方法
- 接口测试中的方法
- nginx+tomcat+memcached实现负载均衡与session共享
- 反转单链表的几种方法
- Makefile中指示符“include”、“-include”和“sinclude”的区别
- HDU5112【水】
- 参加知乎的第一场 值乎
- Lock接口中的几个方法讨论
- UiAutomator笔记之UiObject API(四)
- JS中动态创建元素的三种方法
- 抽象类与接口的思考
- 性能测试工具总结
- resolv.conf中的nameserver
- php基础之常量
- HDU 2824
- 校招第二站-----爱数