1.java.util.concurrent

线程同步:

  • 是因为多线程读写竞争资源需要同步
  • Java语言提供了synchronized/wait/notify来实现同步
  • 编写多线程同步很困难

所以Java提供了更高级的java.util.concurrent包:

  • 更高级的同步功能
  • 简化多线程程序的编写
  • JDK>= 1.5

2.ReetrantLock

java.util.locks.ReentrantLock用于替代synchronized加锁

synchronized是Java语言层面提供的,不需考虑异常

ReentrantLock是普通的Java类,要用try...finally来保证锁能够正确释放



当我们使用ReenTrantLock的时候,我们首先要通过new ReentrantLock()新建一个Lock对象。然后我们先试图用lock()方法获得当前对象的锁。如果我们获得锁成功,就进入try代码,最后在finally中用unlock()来释放这个锁。

注意:lock()方法必须在try代码之外完成。因为lock()可能会失败,而unlock()一定要在finally中完成。

class Count{
final Lock lock = new ReetrantLock(); //获得ReentrantLock对象
public void inc(){
lock.lock(); //获得当前对象的锁可能会失败,所以要放在try...finally外面
try{
n = n + 1;
}finally{
lock.unlock(); //释放锁
}
}

ReentrantLock:

  • 可重入锁,一个线程可多次获取同一个锁
  • lock()方法可获取锁
  • tryLock()方法可尝试获取锁并可指定超时。
class Counter{
final Lock lock = new ReentrantLock();
private void inc() throws InterruptedException{
if(lock.tryLock(1, TimeUnit.SECONDS)){
try{
n = n + 1;
}finally {
lock.unlock();
}
}
}
}

使用ReentrantLock比直接使用synchronized更安全,因为synchronized会导致线程要么获得锁,要的永远等待下去。而使用ReentrantLock的时候,我们通过tryLock()在失败的时候不会导致死锁。

3.示例

import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Lock; class Counter{
private Lock lock = new ReentrantLock();
private int value = 0;
public void add(int m){
lock.lock();
try{
value += m;
}finally {
lock.unlock();
}
}
public void dec(int m){
lock.lock();
try{
value -= m;
}finally {
lock.unlock();
}
}
public int get(){
lock.lock();
try{
return this.value;
}finally {
lock.unlock();
}
}
}
public class Main{
final static int LOOP = 100;
public static void main(String[] args) throws Exception{
Counter counter = new Counter();
Thread t1 = new Thread(){
public void run(){
for(int i=0;i<LOOP;i++){
counter.add(1);
}
}
};
Thread t2 = new Thread(){
public void run(){
for(int i=0;i<LOOP;i++){
counter.dec(1);
}
}
};
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(counter.get());
}
}

4.总结:

  • ReentrantLock可以替代synchronized
  • ReentrantLock获取锁更安全
  • lock()获取锁在try...finally之前
  • 必须使用try... finally保证释放锁

廖雪峰Java11多线程编程-3高级concurrent包-1ReentrantLock的更多相关文章

  1. 廖雪峰Java11多线程编程-3高级concurrent包-5Atomic

    Atomic java.util.concurrent.atomic提供了一组原子类型操作: 如AtomicInteger提供了 int addAndGet(int delta) int increm ...

  2. 廖雪峰Java11多线程编程-3高级concurrent包-4Concurrent集合

    Concurrent 用ReentrantLock+Condition实现Blocking Queue. Blocking Queue:当一个线程调用getTask()时,该方法内部可能让给线程进入等 ...

  3. 廖雪峰Java11多线程编程-3高级concurrent包-6ExecutorService

    Java语言内置多线程支持: 创建线程需要操作系统资源(线程资源,栈空间) 频繁创建和销毁线程需要消耗大量时间 如果可以复用一个线程 线程池: 线程池维护若干个线程,处于等待状态 如果有新任务,就分配 ...

  4. 廖雪峰Java11多线程编程-3高级concurrent包-9Fork_Join

    线程池可以高效执行大量小任务: Fork/Join线程池可以执行一种特殊的任务: 把一个大任务拆成多个小任务并行执行 Fork/Join是在JDK 1.7引入的 示例:计算一个大数组的和 Fork/J ...

  5. 廖雪峰Java11多线程编程-3高级concurrent包-8CompletableFuture

    使用Future可以获得异步执行结果 Future<String> future = executor.submit(task); String result = future.get() ...

  6. 廖雪峰Java11多线程编程-3高级concurrent包-7Future

    JDK提供了ExecutorService接口表示线程池,可以通过submit提交一个任务. ExecutorService executor = Executors.newFixedThreadPo ...

  7. 廖雪峰Java11多线程编程-3高级concurrent包-3Condition

    Condition实现等待和唤醒线程 java.util.locks.ReentrantLock用于替代synchronized加锁 synchronized可以使用wait和notify实现在条件不 ...

  8. 廖雪峰Java11多线程编程-3高级concurrent包-2ReadWriteLock

    ReentrantLock保证单一线程执行 ReentrantLock保证了只有一个线程可以执行临界区代码: 临界区代码:任何时候只有1个线程可以执行的代码块. 临界区指的是一个访问共用资源(例如:共 ...

  9. 廖雪峰Java11多线程编程-2线程同步-3死锁

    1.线程锁可以嵌套 在多线程编程中,要执行synchronized块: 必须首先获得指定对象的锁 Java的线程锁是可重入的锁.对同一个对象,同一个线程,可以多次获取他的锁,即同一把锁可以嵌套.如以下 ...

随机推荐

  1. Hadoop2.X主要模块默认端口及作用

    Hadoop集群的各部分一般都会使用到多个端口,有些是daemon之间进行交互之用,有些是用于RPC访问以及HTTP访问.而随着Hadoop周边组件的增多,完全记不住哪个端口对应哪个应用,特收集记录如 ...

  2. 剑指offer——05重建二叉树

    题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...

  3. CSS3新属性之---flex box布局实例

    flex box布局实例 flex的强大之处在于不管什么布局,几行命令即可实现 /*本节模板div元素(代表骰子的一个面)是Flex容器,span元素(代表一个点)是Flex项目.如果有多个项目,就要 ...

  4. 干货:Java正确获取客户端真实IP方法整理

    在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实I ...

  5. 关于合并pdf文件出现的问题

    输出端出现以下问题: PdfReadWarning: Xref table not zero-indexed. ID numbers for objects will be 解决方案: import ...

  6. Spring Cloud Feign设计原理

    什么是Feign? Feign 的英文表意为“假装,伪装,变形”, 是一个http请求调用的轻量级框架,可以以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直 ...

  7. 唯一id

    package com.debug.kill.server.utils; /** * Created by Administrator on 2019/6/20. */ import org.apac ...

  8. 转: https原理:证书传递、验证和数据加密、解密过程解析

    原本连接:http://www.cnblogs.com/zhuqil/archive/2012/07/23/2604572.html 我们都知道HTTPS能够加密信息,以免敏感信息被第三方获取.所以很 ...

  9. 前端常用的库和实用技术之JavaScript面向切面编程

    Aspect Oriented Programming(AOP)面向切面编程是一个比较热门的话题. AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程 中的某个步骤或阶段,以 ...

  10. java多线程-AbstractQueuedSynchronizer

    大纲: AbstractQueuedSynchronizer简介 aqs基本结构 aqs应用-ReentrantLock.lock aqs应用-ReentrantLock.unlock aqs应用-S ...