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中引入的一系列并发库 ...
随机推荐
- [转帖]Oracle优化案例:vfs_cache_pressure和min_free_kbytes解决RMAN挂起问题
https://www.modb.pro/db/34028 环境: Oracle 11gr2 + dataguard 512GB内存 + 128核cpu + 高性能存储服务器 uname -an Li ...
- drop_caches 的简单学习
drop_caches 的简单学习 背景 最近一段时间一直在学习内存相关的知识 Linux系统里面的内存管理还是非常复杂的. 我这边理解 Linux从宏观层次的 段页式内存管理 到细节的buddy和s ...
- [转帖]前端安全(同源策略、XSS攻击、CSRF攻击)
https://juejin.cn/post/6844904158697357319 同源策略(Same-origin policy) 如果两个 URL 的协议.域名和端口都相同,我们就称这两个 UR ...
- [转帖]RAC AWR重要指标说明
1.Global Cache Load Profile Global Cache blocks received: 接收到的全局缓冲块 Global Cache blocks served: 发送的 ...
- 【转帖】nginx变量使用方法详解-6
https://www.diewufeiyang.com/post/580.html Nginx 内建变量用在"子请求"的上下文中时,其行为也会变得有些微妙. 前面在 (三) 中我 ...
- ipset的学习与使用
ipset的学习与使用 场景说明 虽然可以通过: firewall-cmd --zone=trusted --add-source=$1 --permanent && firewall ...
- [转帖]Xargs用法详解
https://www.cnblogs.com/cheyunhua/p/8796433.html 1. 简介 之所以能用到这个命令,关键是由于很多命令不支持|管道来传递参数,而日常工作中有有这个必要, ...
- [转帖]Redis如何绑定CPU
文章系转载,便于分类和归纳,源文地址:https://www.yisu.com/zixun/672271.html 绑定 CPU Redis 6.0 开始支持绑定 CPU,可以有效减少线程上下文切换. ...
- Oracle 设置白名单过滤
最近有一个需求 要求开发人员不能随便连接测试的数据库 又不想太过复杂,部分人还得进行连结. 查了下往上是有方案的: 就是 TCP_VALIDNODE_CHECKING 参数 解决方法和说明如下 来源 ...
- 你不知道的Linux shell操作
Linux Shell 脚本入门教程 Linux Shell 脚本是一种强大的工具,它允许您自动化日常任务和复杂操作.在本教程中,我们将逐步介绍几个实用的 Shell 脚本示例.每个示例都将详细说明, ...