文档章节

Java并发编程初级篇(十三):使用锁来实现同步机制

阿拉德大陆的魔法师
 阿拉德大陆的魔法师
发布于 2016/11/25 10:41
字数 868
阅读 198
收藏 0

阿里云携手百名商业领袖、技术大咖,带您一探行进中的数字新基建!>>>

Java API除了提供synchronized关键字实现同步机制外,还提供了Lock接口以及它的实现类ReentrantLock。Lock接口除了能够实现同步机制外,还提供了一个tryLock()方法的实现。这个方法会试图获得锁,如果锁已经被其他线程获取,它将返回false并继续往下执行代码。

你会发现使用Lock接口更加灵活,因为synchronized同步代码当A线程进入后,其他视图访问同步代码的线程都会被挂起直到A线程执行完毕。而Lock接口允许你通过编码的方式来决定是否实现同步代码,并且可以使用tryLock()检测锁是否被其他线程获取,如果其他线程拥有锁,那么这个线程可以选择跳过同步代码继续向下执行。

看一个示例:

我们模拟一个打印队列PrintQueue,在这个类中,我们定义一个锁new ReentrantLock(),使用一个随机数等待时间模拟打印过程,在打印开始时加锁,打印结束后在finally块中释放锁,释放锁这一步是必不可少的,不然这个锁一直会被锁定,其他线程就无法获得这个锁,就会造成了死锁。

public class PrintQueue {
    private final Lock queueLock = new ReentrantLock();

    public void printJob(Object document) {
        try {
            queueLock.lock();

            long duration = (long)(Math.random() * 10000);
            System.out.println(Thread.currentThread().getName() +
                    " PrintQueue: print a job during " + (duration/1000) + " seconds");

            Thread.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            queueLock.unlock();
        }
    }
}

创建一个工作线程,调用打印对列类执行打印操作。

public class Job implements Runnable{
    private PrintQueue printQueue;

    public Job(PrintQueue printQueue) {
        this.printQueue = printQueue;
    }

    @Override
    public void run() {
        System.out.printf("%s: Going to print a document.\n", Thread.currentThread().getName());
        printQueue.printJob(new Object());
        System.out.printf("%s: The document has been printed.\n", Thread.currentThread().getName());
    }
}

创建主方法类,新建打印队列并启动10个线程来执行打印操作。

public class Job implements Runnable{
    private PrintQueue printQueue;

    public Job(PrintQueue printQueue) {
        this.printQueue = printQueue;
    }

    @Override
    public void run() {
        System.out.printf("%s: Going to print a document.\n", Thread.currentThread().getName());
        printQueue.printJob(new Object());
        System.out.printf("%s: The document has been printed.\n", Thread.currentThread().getName());
    }
}

查看控制台日志,发现10个打印线程几乎同时启动,但每次只有一个线程能够获取锁并执行打印操作,其他线程等待上一个线程执行完毕释放锁后继续竞争锁,获取锁的线程继续执行,其他线程继续等待,直到所有线程执行完毕。

Thread-0: Going to print a document.
Thread-0 PrintQueue: print a job during 4 seconds
Thread-9: Going to print a document.
Thread-8: Going to print a document.
Thread-7: Going to print a document.
Thread-6: Going to print a document.
Thread-5: Going to print a document.
Thread-4: Going to print a document.
Thread-3: Going to print a document.
Thread-2: Going to print a document.
Thread-1: Going to print a document.
Thread-0: The document has been printed.
Thread-9 PrintQueue: print a job during 2 seconds
Thread-9: The document has been printed.
Thread-8 PrintQueue: print a job during 2 seconds
Thread-8: The document has been printed.
Thread-7 PrintQueue: print a job during 3 seconds
Thread-7: The document has been printed.
Thread-6 PrintQueue: print a job during 8 seconds
Thread-6: The document has been printed.
Thread-5 PrintQueue: print a job during 4 seconds
Thread-5: The document has been printed.
Thread-4 PrintQueue: print a job during 9 seconds
Thread-4: The document has been printed.
Thread-3 PrintQueue: print a job during 8 seconds
Thread-3: The document has been printed.
Thread-2 PrintQueue: print a job during 7 seconds
Thread-2: The document has been printed.
Thread-1 PrintQueue: print a job during 6 seconds
Thread-1: The document has been printed.

 

© 著作权归作者所有

阿拉德大陆的魔法师
粉丝 27
博文 91
码字总数 83019
作品 0
西城
程序员
私信 提问
加载中

评论(0)

读书笔记之《Java并发编程的艺术》-并发编程基础

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
4.1K
8
跳槽时,这些Java面试题99%会被问到

我在 Oracle 已经工作了近 7 年,面试过从初级到非常资深的Java工程师,且由于 Java 组工作任务的特点,我非常注重面试者的计算机科学基础和编程语言的理解深度,可以不要求面试者非要精通 ...

Java小铺
2018/08/15
554
0
Java并发编程的艺术下载 𦄭

<h2>下载地址: <a style="color: blue;" href="http://www.gqylpy.com/di/11">http://www.gqylpy.com/di/11</a></h2> 《Java并发编程的艺术》PDF高清完整版-下载 内容简介   并发编程领域的......

osc_xj7qtbl4
2019/08/17
1
0
读书笔记之《Java并发编程的艺术》-并发编程容器和框架(重要)

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
849
1
读书笔记之《Java并发编程的艺术》-线程池和Executor的子孙们

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
850
1

没有更多内容

加载失败,请刷新页面

加载更多

史上最全的“文件或目录损坏且无法读取”的解决办法大集合

问题描述: G盘打不开文件或目录损坏且无法读取,是因为这个I盘的文件系统内部结构损坏导致的。史上最全的“文件或目录损坏且无法读取”的解决办法大集合具体的恢复方法看正文 工具/软件:极...

计算无敌
58分钟前
9
0
2048游戏的最佳算法是什么? - What is the optimal algorithm for the game 2048?

问题: I have recently stumbled upon the game 2048 . 我最近偶然发现了2048游戏。 You merge similar tiles by moving them in any of the four directions to make "bigger" tiles. 您可......

javail
今天
9
0
Spring Cloud Ribbon 客户端负载均衡

Ribbon客户端组件提供一系列完善的配置选项,比如连接超时、重试、重试算法等,内置可插拔、可定制的负载均衡组件。下面是用到的一些负载均衡策略: 简单轮询负载均衡 加权轮询负载均衡 区域...

泥瓦匠BYSocket
今天
7
0
为什么在Python 3中“范围(1000000000000000(1000000000000001))”这么快?

问题: It is my understanding that the range() function, which is actually an object type in Python 3 , generates its contents on the fly, similar to a generator. 据我了解, ra......

技术盛宴
今天
9
0
OSChina 周四乱弹 —— 卖全家桶!

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @巴拉迪维 :陈慧娴的单曲《与泪抱拥》 陈慧娴的嗓音加上向雪怀的词,这样的经典组合真不多。#今日歌曲推荐# 《与泪抱拥》- 陈慧娴 手机党少年...

小小编辑
今天
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部