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. LeetCode 182. Duplicate Emails (查找重复的电子邮箱)

    题目标签: 题目给了我们一个 email 的table,让我们找到重复的 email. 可以建立 Person a, Person b, 找到两个表格中,emai 相等 但是 id 不同的 email ...

  2. row_number() over(partition by a order by b desc) rn 用法

    转载于:http://www.blogjava.net/kxbin/articles/360195.html 可以看看http://jingyan.baidu.com/article/9989c746 ...

  3. 配置基于Devstack的嵌套KVM虚拟化

    本文为minxihou的翻译文章,转载请注明出处Bob Hou: http://blog.csdn.net/minxihou JmilkFan:minxihou的技术博文方向是 算法&Open ...

  4. [转]ThinkPHP分页实例

    很多人初学thinkphp时,不太熟悉thinkphp的分页使用方法,现在将自己整理的分页方法分享下,有需要的朋友可以看看.   控制器中的代码:   $db = M("cost" ...

  5. GPIO_F427

  6. Web前端开发必备手册(Cheat sheet)

    转自:http://blog.bingo929.com/cheat-sheets-for-web-develop.html Cheat sheet这个词组如果直译成中文,意思大概是”作弊小抄”之类的词 ...

  7. css布局-瀑布流的实现

    一.基本思路 1.先看最终的效果图: 2.实现原理:通过position:absolute(绝对定位)来定位每一个元素的位置,并且将当前列的高度记录下来方便下一个dom位置的计算 二.代码实现 1.版 ...

  8. JDBC_Template(简化代码)

    /** * @Description: TODO(这里用一句话描述这个类的作用) * @Author aikang * @Date 2019/8/27 11:03 */ /* Spring JDBC: ...

  9. ubuntu 权限不够,解决办法,无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用)

    终端执行  sudo passwd root输入root 新密码执行命令  nano /usr/share/lightdm/lightdm.conf.d/50-ubuntu.conf末行添加   gr ...

  10. php curl的正确使用方法

    在做一个读取远程抓取数据并显示的demo的时候,遇到了以下几个问题: 1.用的curl变量进行了多定义 2.抓取远程数据时没有返回正确的json数据 没有返回正确的json数据不是因为网站提供的接口问 ...