Java并发编程实例--16.使用ReentrantLock实现线程同步
Java提供另一机制去同步代码块。它比synchronized关键字更强大且易用。
它是基于Lock接口和其实现类例如:ReentrantLock。
这一机制对比synchronized关键字的优势在于:
1.可以构建更加灵活的同步代码块;
2.Lock接口提供了一些额外功能,例如tryLock()方法,它会返回一个布尔值以表示当前资源是否被锁。
3.Lock接口可以实现读写分离,多个读者但只有一个修改者。
4.Lock接口提供更好的性能。
本例中,我们将通过模拟打印队列去学习如何使用锁去同步代码块。
PrintQueue.java
package com.dylan.thread.ch2.c04.task;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* This class simulates a print queue
*
*/
public class PrintQueue {
/**
* Lock to control the access to the queue.
*/
private final Lock queueLock=new ReentrantLock();
/**
* Method that prints a document
* @param document document to print
*/
public void printJob(Object document){
queueLock.lock();
try {
Long duration=(long)(Math.random()*10000);
System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n",Thread.currentThread().getName(),(duration/1000));
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
queueLock.unlock();
}
}
}
Job.java
package com.dylan.thread.ch2.c04.task;
/**
* This class simulates a job that send a document to print.
*
*/
public class Job implements Runnable {
/**
* Queue to print the documents
*/
private PrintQueue printQueue;
/**
* Constructor of the class. Initializes the queue
* @param printQueue
*/
public Job(PrintQueue printQueue){
this.printQueue=printQueue;
}
/**
* Core method of the Job. Sends the document to the print queue and waits
* for its finalization
*/
@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());
}
}
Main.java
package com.dylan.thread.ch2.c04.core;
import com.dylan.thread.ch2.c04.task.Job;
import com.dylan.thread.ch2.c04.task.PrintQueue;
/**
* Main class of the example.
*
*/
public class Main {
/**
* Main method of the class. Run ten jobs in parallel that
* send documents to the print queue at the same time.
*/
public static void main (String args[]){
// Creates the print queue
PrintQueue printQueue=new PrintQueue();
// Creates ten Threads
Thread thread[]=new Thread[10];
for (int i=0; i<10; i++){
thread[i]=new Thread(new Job(printQueue),"Thread "+i);
}
// Starts the Threads
for (int i=0; i<10; i++){
thread[i].start();
}
}
}
运行结果:
Thread 0: Going to print a document
Thread 5: Going to print a document
Thread 0: PrintQueue: Printing a Job during 0 seconds
Thread 8: Going to print a document
Thread 7: Going to print a document
Thread 3: Going to print a document
Thread 1: Going to print a document
Thread 4: Going to print a document
Thread 2: Going to print a document
Thread 9: Going to print a document
Thread 6: Going to print a document
Thread 0: The document has been printed
Thread 5: PrintQueue: Printing a Job during 7 seconds
Thread 5: The document has been printed
Thread 8: PrintQueue: Printing a Job during 0 seconds
Thread 7: PrintQueue: Printing a Job during 5 seconds
Thread 8: The document has been printed
Thread 7: The document has been printed
Thread 3: PrintQueue: Printing a Job during 7 seconds
Thread 3: The document has been printed
Thread 1: PrintQueue: Printing a Job during 3 seconds
Thread 1: The document has been printed
Thread 4: PrintQueue: Printing a Job during 7 seconds
Thread 4: The document has been printed
Thread 2: PrintQueue: Printing a Job during 5 seconds
Thread 9: PrintQueue: Printing a Job during 8 seconds
Thread 2: The document has been printed
Thread 9: The document has been printed
Thread 6: PrintQueue: Printing a Job during 4 seconds
Thread 6: The document has been printed
Java并发编程实例--16.使用ReentrantLock实现线程同步的更多相关文章
- java并发编程JUC第九篇:CountDownLatch线程同步
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...
- Java并发编程锁系列之ReentrantLock对象总结
Java并发编程锁系列之ReentrantLock对象总结 在Java并发编程中,根据不同维度来区分锁的话,锁可以分为十五种.ReentranckLock就是其中的多个分类. 本文主要内容:重入锁理解 ...
- Java并发编程(二)如何保证线程同时/交替执行
第一篇文章中,我用如何保证线程顺序执行的例子作为Java并发系列的开胃菜.本篇我们依然不会有源码分析,而是用另外两个多线程的例子来引出Java.util.concurrent中的几个并发工具的用法. ...
- 【Java并发编程实战】----- AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...
- 【Java并发编程实战】—– AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形. 其主要从双方面进行了改造:节点的结构与节点等待机制.在结构上引入了 ...
- Java并发编程实战.笔记十一(非阻塞同步机制)
关于非阻塞算法CAS. 比较并交换CAS:CAS包含了3个操作数---需要读写的内存位置V,进行比较的值A和拟写入的新值B.当且仅当V的值等于A时,CAS才会通过原子的方式用新值B来更新V的值,否则不 ...
- 【Java并发编程】15、ReentrantLock实现原理深入探究
原文已经写得非常详细了,直接把大神的文章转发过来了 https://www.cnblogs.com/xrq730/p/4979021.html 前言 这篇文章被归到Java基础分类中,其实真的一点都 ...
- Java并发编程实例(synchronized)
此处用一个小程序来说明一下,逻辑是一个计数器(int i):主要的逻辑功能是,如果同步监视了资源i,则不输出i的值,但如果没有添加关键字synchronized,因为是两个线程并发执行,所以会输出i的 ...
- 那些年读过的书《Java并发编程实战》一、构建线程安全类和并发应用程序的基础
1.线程安全的本质和线程安全的定义 (1)线程安全的本质 并发环境中,当多个线程同时操作对象状态时,如果没有统一的状态访问同步或者协同机制,不同的线程调度方式和不同的线程执行次序就会产生不同的不正确的 ...
- Java 并发编程中的 Executor 框架与线程池
Java 5 开始引入 Conccurent 软件包,提供完备的并发能力,对线程池有了更好的支持.其中,Executor 框架是最值得称道的. Executor框架是指java 5中引入的一系列并发库 ...
随机推荐
- [转帖]使用 goofys 挂载 S3 bucket 为文件系统
https://xie.infoq.cn/article/7f178e0a1315f758d77c6c2bb 背景 公司的 gitlab 目前都是直接存储在物理盘上,为了确保数据不会丢失,需要重复多次 ...
- 【转帖】SmartNIC — TSO、GSO、LRO、GRO 技术
目录 文章目录 目录 TSO(TCP Segmentation Offload) GSO(Generic Segmentation Offload) LRO(Large Receive Offload ...
- [转帖]从DDR到DDR4,内存核心频率基本上就没太大的进步!
https://zhuanlan.zhihu.com/p/84194049 从2001年DDR内存面世以来发展到2019年的今天,已经走过了DDR.DDR2.DDR3.DDR4四个大的规格时代了(DD ...
- 使用smem 计算Oracle用户下内存占用情况.
1. 本来计划使用 ps 命令进行查看, 但是发现ps 最多查询出来的是 RSS的内存数据, 会多添加很多冗余的内存数据量进来, 于是作罢 2. 找了下公司的方神, 说可以使用smem 然后简单看了下 ...
- mysql8 CentOS7 简要安装说明
1. 卸载mariadb rpm -qa |grep mariadb |xargs yum remove -y比较简单的卸载办法. 2. 安装所有的rpm包. yum localinstall *.r ...
- 使用Configmap 配置 springboot的application.yaml文件的方式部署环境的方法
Configmap部署k8s下Springboot服务的办法 前提 日常工作中需要使用k8s部署微服务环境, 但是内部的数据库连接和redis等连接非常麻烦,使用helm chart 进行变量替换时非 ...
- .Net Core 3.1浏览器后端服务(二) Web API项目分层
一.前言 分层开发的思想在计算机领域中至关重要,从操作系统到软件设计,分层思想无处不在. 在搭建项目的分层结构前,先简单了解下分层的优缺点.如下图,分为(呈现层.业务层.服务层.数据层) 分层的优点: ...
- gRPC如何保障数据安全传输
什么是 gRPC? gRPC 是由 Google 开发的高性能.开源的 RPC(Remote Procedure Call)框架,用于在客户端和服务器之间进行通信.它基于 Protocol Buffe ...
- 深度学习应用篇-自然语言处理-命名实体识别[9]:BiLSTM+CRF实现命名实体识别、实体、关系、属性抽取实战项目合集(含智能标注)
深度学习应用篇-自然语言处理-命名实体识别[9]:BiLSTM+CRF实现命名实体识别.实体.关系.属性抽取实战项目合集(含智能标注) 1.命名实体识别介绍 命名实体识别(Named Entity R ...
- 【操作系统和计网从入门到深入】(四)基础IO和文件系统
前言 这个专栏其实是博主在复习操作系统和计算机网络时候的笔记,所以如果是博主比较熟悉的知识点,博主可能就直接跳过了,但是所有重要的知识点,在这个专栏里面都会提到!而且我也一定会保证这个专栏知识点的完整 ...