ConCurrent并发包 - Lock详解(转)
synchronized的缺陷
- 获取锁的线程执行完该段代码,线程会释放占有的锁;
- 线程执行发生异常,此时JVM会让线程自动释放锁。
concurrent.locks包下常用类
- public interface Lock {
- void lock();
- void lockInterruptibly() throws InterruptedException;
- boolean tryLock();
- boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
- void unlock();
- Condition newCondition();
- }
- lock()方法用来获取锁。
- tryLock()尝试获取锁,如果成功则返回true,失败返回false(其他线程已占有锁)。这个方法会立即返回,在拿不到锁时也不会等待。
- tryLock(long time, TimeUnit unit)方法和tryLock()方法类似,只不过在拿不到锁时等待一定的时间,如果超过等待时间还拿不到锁就返回false。
- lockInterruptibly()方法比较特殊,当通过这个方法获取锁时,如果该线程正在等待获取锁,则它能够响应中断。也就是说,当两个线程同时通过lockInterruptibly()获取某个锁时,假如线程A获得了锁,而线程B仍在等待获取锁,那么对线程B调用interrupt()方法可以中断B的等待过程。
- // lock()的使用
- Lock lock = ...;
- lock.lock();
- try{
- //处理任务
- }catch(Exception ex){
- }finally{
- lock.unlock(); //释放锁
- }
- // tryLock()的使用
- Lock lock = ...;
- if(lock.tryLock()) {
- try{
- //处理任务
- }catch(Exception ex){
- }finally{
- lock.unlock(); //释放锁
- }
- }else {
- //如果不能获取锁,则直接做其他事情
- }
- // lockInterruptibly()的使用
- public void method() throws InterruptedException {
- lock.lockInterruptibly();
- try {
- //.....
- }
- finally {
- lock.unlock();
- }
- }
使用synchronized关键字,当线程处于等待锁的状态时,是无法被中断的,只能一直等待。
- 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();
- }
- }
- }
例2, lockInterruptibly()响应中断的使用方法:
- public class Test {
- private Lock lock = new ReentrantLock();
- public static void main(String[] args) {
- Test test = new Test();
- MyThread thread1 = new MyThread(test);
- MyThread thread2 = new MyThread(test);
- thread1.start();
- thread2.start();
- try {
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- thread2.interrupt();
- }
- public void insert(Thread thread) throws InterruptedException{
- lock.lockInterruptibly(); //注意,如果需要正确中断等待锁的线程,必须将获取锁放在外面,然后将InterruptedException抛出
- try {
- System.out.println(thread.getName()+"得到了锁");
- long startTime = System.currentTimeMillis();
- for( ; ;) {
- if(System.currentTimeMillis() - startTime >= Integer.MAX_VALUE)
- break;
- //插入数据
- }
- }
- finally {
- System.out.println(Thread.currentThread().getName()+"执行finally");
- lock.unlock();
- System.out.println(thread.getName()+"释放了锁");
- }
- }
- }
- class MyThread extends Thread {
- private Test test = null;
- public MyThread(Test test) {
- this.test = test;
- }
- @Override
- public void run() {
- try {
- test.insert(Thread.currentThread());
- } catch (InterruptedException e) {
- System.out.println(Thread.currentThread().getName()+"被中断");
- }
- }
- }
3. ReadWriteLock
- public interface ReadWriteLock {
- /**
- * Returns the lock used for reading.
- */
- Lock readLock();
- /**
- * Returns the lock used for writing.
- */
- Lock writeLock();
- }
readLock()用来获取读锁,writeLock()用来获取写锁。也就是将文件的读写操作分开,分成两个锁来分配给线程,从而使多个线程可以同时进行读操作。ReentrantReadWriteLock是它的实现类。
- 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();
- }
- }
- }
ConCurrent并发包 - Lock详解(转)的更多相关文章
- 【java多线程】ConCurrent并发包 - Lock详解
synchronized的缺陷 我们知道,可以利用synchronized关键字来实现共享资源的互斥访问. Java 5在java.util.concurrent.locks包下提供了另一种来实现 ...
- C++11 并发指南三(Lock 详解)(转载)
multithreading 多线程 C++11 C++11多线程基本使用 C++11 并发指南三(Lock 详解) 在 <C++11 并发指南三(std::mutex 详解)>一文中我们 ...
- C++11 并发指南三(Lock 详解)
在 <C++11 并发指南三(std::mutex 详解)>一文中我们主要介绍了 C++11 标准中的互斥量(Mutex),并简单介绍了一下两种锁类型.本节将详细介绍一下 C++11 标准 ...
- java.util.concurrent.atomic 类包详解
java.util.concurrent包分成了三个部分,分别是java.util.concurrent.java.util.concurrent.atomic和java.util.concurren ...
- JAVA中synchronized和lock详解
目前在Java中存在两种锁机制:synchronized和Lock,Lock接口及其实现类是JDK5增加的内容,其作者是大名鼎鼎的并发专家Doug Lea.本文并不比较synchronize ...
- Lock详解
在JDK1.5后,并发包里新增了Lock接口以及其实现类来实现锁功能,它提供了与synchronized关键字类似的锁功能,但它需要手动开启.关闭锁.虽然看起来没有synchronized方便,但它可 ...
- FLUSH TABLE WITH READ LOCK详解
FLUSH TABLES WITH READ LOCK简称(FTWRL),该命令主要用于备份工具获取一致性备份(数据与binlog位点匹配).由于FTWRL总共需要持有两把全局的MDL锁,并且还需要关 ...
- MySQL Metadata Lock详解
Metadata Lock 的作用: 要直接说出Metadata Lock 的作用.以我目前的文字功底是不行的.好在我可以通过一个例子来说明. 假设session 1 在正在执行如下的SQL语句 se ...
- 详解synchronized与Lock的区别与使用
知识点 1.线程与进程 在开始之前先把进程与线程进行区分一下,一个程序最少需要一个进程,而一个进程最少需要一个线程.关系是线程–>进程–>程序的大致组成结构.所以线程是程序执行流的最小单位 ...
随机推荐
- 006 Java并发编程wait、notify、notifyAll和Condition
原文https://www.cnblogs.com/dolphin0520/p/3920385.html#4182690 Java并发编程:线程间协作的两种方式:wait.notify.notifyA ...
- 2015多校第6场 HDU 5354 Bipartite Graph CDQ,并查集
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5354 题意:求删去每个点后图是否存在奇环(n,m<=1e5) 解法:很经典的套路,和这题一样:h ...
- python 结束练习
1.文件操作有哪些模式?请简述各模式的作用 r 只读模式 r+ 读写 rb w 只写模式 w+ 写读 wb x 只写模式 x+ 写读 xb a 追加模式 a+ 写读 ab 2.s = '**hello ...
- 【python】日志系统
来源: http://blog.csdn.net/wykgf/article/details/11576721 http://www.jb51.net/article/42626.htm http:/ ...
- 机器学习方法(八):随机采样方法整理(MCMC、Gibbs Sampling等)
转载请注明出处:Bin的专栏,http://blog.csdn.net/xbinworld 本文是对参考资料中多篇关于sampling的内容进行总结+搬运,方便以后自己翻阅.其实参考资料中的资料写的比 ...
- Restore IP Addresses——边界条件判定
Given a string containing only digits, restore it by returning all possible valid IP address combina ...
- Find Peak Element——二分查找的变形
A peak element is an element that is greater than its neighbors. Given an input array where num[i] ≠ ...
- Convolutional Neural Networks卷积神经网络
转自:http://blog.csdn.net/zouxy09/article/details/8781543 9.5.Convolutional Neural Networks卷积神经网络 卷积神经 ...
- AC日记——The Shortest Path in Nya Graph hdu 4725
4725 思路: 拆点建图跑最短路: 代码: #include <cstdio> #include <cstring> #include <iostream> #i ...
- 也记一次性能优化:LINQ to SQL中Contains方法的优化
距离上一篇博文更新已经两个月过去了.在此,先表一表这两个月干了些啥: 世界那么大,我也想去看看.四月份的时候,我入职了上海的一家电商公司,职位是.NET高级开发工程师.工作一个月,最大的感受是比以前小 ...