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.线程与进程 在开始之前先把进程与线程进行区分一下,一个程序最少需要一个进程,而一个进程最少需要一个线程.关系是线程–>进程–>程序的大致组成结构.所以线程是程序执行流的最小单位 ...
随机推荐
- Socket与URL通信比较
转至链接:http://blog.csdn.net/qq_15848173/article/details/46328399 利用URL通信和Socket进行通信有很多相似之处.他们都是利用建立连接. ...
- 修改mysql权限
关于mysql的用户管理,笔记 1.创建新用户 通过root用户登录之后创建 >> grant all privileges on *.* to testuser@localhost id ...
- hdu 3667(最小费用最大流+拆边)
Transportation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- Mysql优化之my.cnf参数优化
1.innodb_buffer_pool_size innodb_buffer_pool_size 参数用来设置Innodb 最主要的Buffer(Innodb_Buffer_Pool)的大小,也就是 ...
- asp.net webform 打造私人后台管理系统(附源码)
系统简介 git地址:https://github.com/qingfengjun/XSSystem 不少人让我做公司的网站,要求不多,但是需要有一个后台系统,所以就有了开发的动力.也想做个系统自己学 ...
- 利用Node 搭配uglify-js压缩js文件,批量下载图片到本地
Node的便民技巧-- 压缩代码 下载图片 压缩代码 相信很多前端的同学都会在上线前压缩JS代码,现在的Gulp Webpack Grunt......都能轻松实现.但问题来了,这些都不会,难道就要面 ...
- css3翻书效果
强大的css3不需要解释,代码分层理解[直接复制],很有意思. 效果图: <ul class="align"> <li> <figure class= ...
- hdu多校第三场
Problem D. Euler Function 思路:打表找找规律. #include<bits/stdc++.h> #define LL long long #define fi f ...
- 六十三 、异步IO
在IO编程一节中,我们已经知道,CPU的速度远远快于磁盘.网络等IO.在一个线程中,CPU执行代码的速度极快,然而,一旦遇到IO操作,如读写文件.发送网络数据时,就需要等待IO操作完成,才能继续进行下 ...
- Jenkins+maven+Tomcat配置发布
jenkins大多数情况下都是用来部署Java项目,Java项目有一个特点是需要编译和打包的,一般情况下编译和打包都是用maven完成,所以系统环境中需要安装maven. 实验环境: 10.0.0.1 ...