文档章节

Java 复习 —— 锁以及线程之间的通讯

learn_more
 learn_more
发布于 2015/09/13 14:48
字数 887
阅读 131
收藏 16


1、Lock

1)1.5版本之后出现,java.util.concurrent.locks.Lock

2) Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition 对象。 锁是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问。一次只能有一个线程获得锁,对共享资源的所有访问都需要首先获得锁。不过,某些锁可能允许对共享资源并发访问,如 ReadWriteLock 的读取锁。 

3)一般使用的Lock替代synchronized的代码如下:

     private Lock l = new ReentrantLock(); 
     l.lock();
     try {
         // access the resource protected by this lock
     } finally {
         l.unlock();
     }

4)和synchronized一样,也可以在线程之间进行通讯,如下代码:

class Data {
    private int number = 0;// 共享变量
    private Lock lock = new ReentrantLock(); // 一种互斥锁
    private Condition c1 = lock.newCondition(); // 锁上的一个条
    private Condition c2 = lock.newCondition(); // 锁上的另一个条件
    
    public Data(){
        System.out.println( c1 == c2); // 返回false,一个lock可以拥有多个独立的condition
    }
    
    public int increase(){
        lock.lock();// 对共享变量的操作必须加锁,而且线程通讯必须在拥有的锁的基础上
        try{
            if(number != 0){ // 这里没有必要使用循环判断,但是Object.wait必须在循环中判断
                try {
                    c1.await(); // 如果调用c1的方法,那么后面满足条件就应该对应唤醒c1
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            number++;
            c2.signal(); // 唤醒等待池中的c2
        }finally{
            lock.unlock(); // 所有的加锁之后的操作都必须使用规定的代码结构来完成
        }
        return number;
    }
    
    public int decrease(){
        lock.lock(); // 对共享变量的操作必须加锁,而且线程通讯必须在拥有的锁的基础上
        try{
            if(number != 1){// 这里没有必要使用循环判断,但是Object.wait必须在循环中判断
                try {
                    c2.await();  // 如果调用c2的方法,那么后面满足条件就应该对应唤醒c2
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            number--;
            c1.signal(); // 唤醒等待池中的c1
        }finally{
            lock.unlock();// 所有的加锁之后的操作都必须使用规定的代码结构来完成
        }
        return number;
    }
    
}


2、Lock 与 synchronized 的比较

1)在JDK 5,Synchronized 要比 Lock 慢很多,但是在 JDK 6 中,它们的效率差不多。

2)Synchronized是Lock的一种简化实现,一个Lock可以对应多个 Condition,而synchronized把Lock和Condition合并了,一个 synchronized Lock只对应一个Condition,可以说Synchronized是Lock 的简化版本。

3)方法对比,使用synchronized的时候都是使用 wait、notify;如果使用Lock,那么需要使用condition的await、singal



3、Lock的一些子类

1)ReentrantLock 一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大,一般情况下我们只要使用这个对象就可以搞定了!

2)ReentrantReadWriteLock.ReadLock  对于一些只读的操作我们可以赋予它共享锁,也就是读锁,可以多个线程同时读数据,但是不能写数据。lock = new ReentrantReadWriteLock().readLock(); 

3)ReentrantReadWriteLock.WriteLock  对于写操作,那么为了避免脏读,所以我们应该给他加排它锁,这样只能写,不能读,lock = new ReentrantReadWriteLock.WriteLock();





© 著作权归作者所有

learn_more
粉丝 93
博文 240
码字总数 210196
作品 0
深圳
程序员
私信 提问
再有人问你synchronized是什么,就把这篇文章发给他。

在《深入理解Java虚拟机》中,有这样一段话: synchronized关键字在需要原子性、可见性和有序性这三种特性的时候都可以作为其中一种解决方案,看起来是“万能”的。的确,大部分并发控制操作...

Java填坑之路
2018/08/07
0
0
【死磕Java并发】—– 死磕 Java 并发精品合集

【死磕 Java 并发】系列是 LZ 在 2017 年写的第一个死磕系列,一直没有做一个合集,这篇博客则是将整个系列做一个概览。 先来一个总览图: 【高清图,请关注“Java技术驿站”公众号,回复:脑...

chenssy
2018/07/22
0
0
ForkJoinPool 探索

介绍 “分而治之“是理清思路和解决问题的一个重要的方法。大到系统架构对功能模块的拆分,小到归并排序的实现,无一不在散发着分而治之的思想。在实现分而治之的算法的时候,我们通常使用递...

robinhan
01/10
0
0
悲观的并发策略——synchronized互斥锁

互斥锁是最常见的同步手段,在并发过程中,当多条线程对同一个共享数据竞争时,它保证共享数据同一时刻只能被一条线程使用,其他线程只有等到锁释放后才能重新进行竞争。 对于Java开发人员,...

wangyangzhizhou
2018/04/16
0
0
Java面试需要准备哪些多线程并发的技术要点

一、概念 什么是线程 一个线程要执行任务,必须得有线程 一个进程(程序)的所有任务都在线程中执行的 一个线程执行任务是串行的,也就是说一个线程,同一时间内,只能执行一个任务 多线程原理 同一...

码蚁说架构
2018/05/31
0
0

没有更多内容

加载失败,请刷新页面

加载更多

你知道多少this,new,bind,call,apply?那我告诉你

那么什么是this,new,bind,call,apply呢?这些你都用过吗?掌握这些内容都是基础中的基础了。如果你不了解,那还不赶快去复习复习,上网查阅资料啥的! 通过call,apply,bind可以改变thi...

达达前端小酒馆
今天
4
0
设计模式之命令模式

命令模式的类图 其中的角色有: Client 客户端。只依赖于调用者Invoker、接收者Receiver、以及Command(网上找的图片这里没有画出来),不用关注接收者如何执行命令,只需要告诉调用者需要执行...

陈年之后是青葱
今天
7
0
2. 彤哥说netty系列之IO的五种模型

你好,我是彤哥,本篇是netty系列的第二篇。 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识。 简介 本文将介绍linux中的五种IO模型,同时也会介绍阻塞/非阻塞与同步/异步的区别。 何...

彤哥读源码
今天
5
0
OSChina 周四乱弹 —— 喵的波粒二象性

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @ 小小编辑推荐:《水墨兰亭》- 李志辉 《水墨兰亭》- 李志辉 手机党少年们想听歌,请使劲儿戳(这里) @巴拉迪维 :卧室里采光要足够好,这样...

小小编辑
今天
34
1
前后端分离接口规范

最近在开发,遇到前后端关于Boolean类型的参数传参和接收的问题: 场景:后台会根据用户是否出车/是否出司机(Boolean类型)来决定后端的业务逻辑(比如费用的计算),前端使用JSON字符串类型...

code-ortaerc
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部