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实现线程同步的更多相关文章

  1. java并发编程JUC第九篇:CountDownLatch线程同步

    在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...

  2. Java并发编程锁系列之ReentrantLock对象总结

    Java并发编程锁系列之ReentrantLock对象总结 在Java并发编程中,根据不同维度来区分锁的话,锁可以分为十五种.ReentranckLock就是其中的多个分类. 本文主要内容:重入锁理解 ...

  3. Java并发编程(二)如何保证线程同时/交替执行

    第一篇文章中,我用如何保证线程顺序执行的例子作为Java并发系列的开胃菜.本篇我们依然不会有源码分析,而是用另外两个多线程的例子来引出Java.util.concurrent中的几个并发工具的用法. ...

  4. 【Java并发编程实战】----- AQS(四):CLH同步队列

    在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...

  5. 【Java并发编程实战】—– AQS(四):CLH同步队列

    在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形. 其主要从双方面进行了改造:节点的结构与节点等待机制.在结构上引入了 ...

  6. Java并发编程实战.笔记十一(非阻塞同步机制)

    关于非阻塞算法CAS. 比较并交换CAS:CAS包含了3个操作数---需要读写的内存位置V,进行比较的值A和拟写入的新值B.当且仅当V的值等于A时,CAS才会通过原子的方式用新值B来更新V的值,否则不 ...

  7. 【Java并发编程】15、ReentrantLock实现原理深入探究

    原文已经写得非常详细了,直接把大神的文章转发过来了  https://www.cnblogs.com/xrq730/p/4979021.html 前言 这篇文章被归到Java基础分类中,其实真的一点都 ...

  8. Java并发编程实例(synchronized)

    此处用一个小程序来说明一下,逻辑是一个计数器(int i):主要的逻辑功能是,如果同步监视了资源i,则不输出i的值,但如果没有添加关键字synchronized,因为是两个线程并发执行,所以会输出i的 ...

  9. 那些年读过的书《Java并发编程实战》一、构建线程安全类和并发应用程序的基础

    1.线程安全的本质和线程安全的定义 (1)线程安全的本质 并发环境中,当多个线程同时操作对象状态时,如果没有统一的状态访问同步或者协同机制,不同的线程调度方式和不同的线程执行次序就会产生不同的不正确的 ...

  10. Java 并发编程中的 Executor 框架与线程池

    Java 5 开始引入 Conccurent 软件包,提供完备的并发能力,对线程池有了更好的支持.其中,Executor 框架是最值得称道的. Executor框架是指java 5中引入的一系列并发库 ...

随机推荐

  1. [转帖]Shell编程之正则表达式与文本处理器(grep、sort、uniq、tr、cut)

    目录 正则表达式概念 正则表达式的作用 元字符 grep命令在文本中查找指定的字符串 sort命令排序 uniq命令快捷去重 tr命令替换.压缩和删除 cut命令快速裁剪命令 expr substr ...

  2. [转帖]学习如何编写 Shell 脚本(基础篇)

    https://juejin.cn/post/6930013333454061575 前言 如果仅仅会 Linux 一些命令,其实已经可以让你在平时的工作中游刃有余了.但如果你还会编写 Shell 脚 ...

  3. [转帖]配置ftp连接对象存储bucket子目录的方法

    https://developer.jdcloud.com/article/1838 配置ftp连接对象存储bucket子目录的方法  京东云技术交付部  2021-01-27 IP归属:未知 441 ...

  4. [转帖]理解 postgresql.conf 的work_mem 参数配置

    https://developer.aliyun.com/article/401250 简介: 主要是通过具体的实验来理解 work_mem 今天我们着重来了解 postgresql.conf 中的 ...

  5. [转帖]使用SkyWalking监控nginx (以openresty为例)

    https://www.cnblogs.com/hahaha111122222/p/15829737.html 安装使用SkyWalking先看这篇文章,地址:https://www.cnblogs. ...

  6. [转帖]基于 Skywalking 部署应用性能监控

    https://www.jianshu.com/p/50627b9ab0be 今天我们就着重讲一讲如何基于 Skywalking 来快速搭建一套应用性能监控平台   walkingfunny.com. ...

  7. [转帖]2.20 Native Operating System Tools

    https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr020.html#BABBHHIE 2.20  ...

  8. 拼多多的U盘都是垃圾

    春节期间陪孩子玩拼多多的果园, 然后发现推送的U盘很便宜就买了下 结果发现.. U盘都是扩容盘,非常垃圾 如下图: 警告: 只有 255933 MB可测试,总容量 255935 MB. 媒体很可能已损 ...

  9. vue3动态路由的addRoute和removeRoute使用

    为什么需要有动态路由 有些时候,我们不同的身份角色,我们希望可以展示不同的菜单. 比如说:普通用户只有展示A菜单,管理员有A,B,C菜单 这个时候,我们就需要动态路由了! Vue2和vue3的区别 V ...

  10. Spring WebSocket实现实时通信的详细教程

    简介 WebSocket 是基于TCP/IP协议,独立于HTTP协议的通信协议.WebSocket 连接允许客户端和服务器之间的全双工通信,以便任何一方都可以通过已建立的连接将数据推送到另一方. 我们 ...