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.线程与进程 在开始之前先把进程与线程进行区分一下,一个程序最少需要一个进程,而一个进程最少需要一个线程.关系是线程–>进程–>程序的大致组成结构.所以线程是程序执行流的最小单位 ...
随机推荐
- 【Educationcal Codeforces Round 21】
这场edu我原本以为能清真一点…… 后来发现不仅是七题 还有各种奇奇怪怪的骚操作…… A. 随便枚举 #include<bits/stdc++.h> using namespace std ...
- 文字顺时针旋转90度(纵向)&古诗词排版
1.文字旋转90度 width: 100px; height: 200px; line-height: 100px; text-align: center; writing-mode: vertica ...
- NOIP 2012 Day1
tags: NOIP 模拟 倍增 高精 Python categories: 信息学竞赛 总结 Luogu P1079 Vigenère 密码 Solution 表示并不是很懂其他人发的题解. 我是这 ...
- shell 中的<,<<,>,>>
相信熟悉linux的童鞋不会对这四个符合陌生,shell脚本的文件流有时候真的挺容易搞晕人的,下面我们一起了解一下吧 参考链接:http://www.cnblogs.com/chengmo/archi ...
- js刷新页面代码
第一种: location.reload() 第二种: location.replace(location.href) 第三种: history.go() 第四种: location=location ...
- python基础(3)---流程控制
流程控制 与C语言不通的是python的流程控制代码块不是用{}花括号表示的,而是强制缩进来控制的:而且缩进必须一致,官方推荐是使用4个空格,不建议使用tab(制表符)做缩进,一是不同的系统tab所占 ...
- react表单提交
class FlavorForm extends React.Component { constructor(props) { super(props); this.state = {value: ' ...
- Linux:hping高级主机扫描
https://www.aliyun.com/jiaocheng/167107.html https://blog.csdn.net/weixin_39762926/article/details/7 ...
- Android studio 导入工程 出现错误
原文:http://blog.csdn.net/qazzxc111/article/details/48787419 对于刚开始使用Android studio 并且以前不了解gradle,IDE之类 ...
- hdu5782
官方题解不是很详细 首先有一个结论:若A=pa+sa B=pb+sb A.B串循环同构,则可以构造一个可行方案(pa,sb) (sa,pb)中有一个是最长匹配,这个不难用反证法证明. 对于s1,s2串 ...