Java马士兵高并发编程视频学习笔记(二)
1.ReentrantLock的简单使用
Reentrant n.再进入
ReentrantLock 一个可重入互斥Lock具有与使用synchronized方法和语句访问的隐式监视锁相同的基本行为和语义,但具有扩展功能。(从jdk1.8中文版复制而来)
可以完成synchronized相同的作用,但必须手动释放锁
- package com.dingyu2;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- /**
- * Reentrant n.再进入
- * ReentrantLock 一个可重入互斥Lock具有与使用synchronized方法和语句访问的隐式监视锁相同的基本行为和语义,但具有扩展功能。(从jdk1.8中文版复制而来)
- * 可以完成synchronized相同的作用,但必须手动释放锁
- * @author dingyu
- *
- */
- public class ReentrantLock1 {
- private Lock lock = new ReentrantLock();
- public void m1() {
- try {
- lock.lock();//synchronized(this)类似,锁定的是堆的对象
- for (int i = 0; i < 10; i++)
- System.out.println("m1-" + i);
- } catch (Exception e) {
- System.out.println("m1启动");
- } finally {
- System.out.println("m1结束");
- lock.unlock();
- }
- }
- public void m2() {
- try {
- lock.lock();
- for (int i = 0; i < 10; i++)
- System.out.println("m2-" + i);
- } catch (Exception e) {
- System.out.println("m2启动");
- } finally {
- System.out.println("m2结束");
- lock.unlock();
- }
- }
- public static void main(String[] args) {
- ReentrantLock1 reentrantLock1 = new ReentrantLock1();
- new Thread(() -> reentrantLock1.m1()).start();
- new Thread(() -> reentrantLock1.m2()).start();
- }
- }
2.ReentrantLock对synchronized的扩展之tryLock()
- package com.dingyu2;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- /**
- * ReentrantLock对synchronized的扩展之tryLock()
- *
- * @author dingyu
- *
- */
- public class ReentrantLock2 {
- private Lock lock = new ReentrantLock();
- public void m1() {
- lock.lock();// 一直锁着,不手动释放, 和synchronized(this)类似,锁定的是堆的对象
- }
- public void m2() {
- boolean isNotLock = lock.tryLock();// 如果别的进程锁着就返回false,如果没锁返回true
- // 我们可以根据有没有锁来执行自己的逻辑,而不需要等着锁的释放,更加灵活
- if (isNotLock) {
- System.out.println("lock对象没有被锁定");
- } else {
- System.out.println("lock对象被锁定了");
- }
- }
- public static void main(String[] args) {
- ReentrantLock2 reentrantLock2 = new ReentrantLock2();
- new Thread(() -> reentrantLock2.m1()).start();
- new Thread(() -> reentrantLock2.m2()).start();
- }
- }
3.ReentranLock对synchronized的扩展:可以被另外的线程打断
- package com.dingyu2;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- /**
- * ReentranLock对synchronized的扩展:可以被另外的线程打断
- * 因为m1方法一直占着锁,m2永远不可能得到锁,既然得不到锁,我们就关闭m2好了,这时候得用lockInterruptibly
- *
- * @author dingyu
- *
- */
- public class ReentrantLock3 {
- private Lock lock = new ReentrantLock();
- public void m1() {
- lock.lock();
- try {
- System.out.println("t1 start");
- while (true) {
- }
- } finally {
- lock.unlock();
- System.out.println("t1 end");
- }
- }
- public void m2() {
- try {
- lock.lockInterruptibly();
- System.out.println("t2 start");
- } catch (InterruptedException e) {
- System.out.println("t2被打断了");
- } finally {
- if (lock.tryLock())
- lock.unlock();
- System.out.println("t2 end");
- }
- }
- public static void main(String[] args) {
- ReentrantLock3 reentrantLock3 = new ReentrantLock3();
- Thread t1 = new Thread(() -> reentrantLock3.m1(), "t1");
- t1.start();
- Thread t2 = new Thread(() -> reentrantLock3.m2(), "t2");
- t2.start();
- t2.interrupt();
- }
- }
4.ReentrantLock对synchronized的扩展 : 可以指定公平锁
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- /**
- * ReentrantLock对synchronized的扩展 : 可以指定公平锁,哪个线程等待时间长,哪个先执行
- * 在构造函数中放入ture参数
- *
- * @author dingyu
- *
- */
- public class ReentrantLock4 {
- private Lock lock = new ReentrantLock(true);
- public void m1() {
- for (int i = 0; i < 10; i++) {
- try {
- lock.lock();
- System.out.println(Thread.currentThread().getName() + "running");
- } finally {
- lock.unlock();
- }
- }
- }
- public static void main(String[] args) {
- ReentrantLock4 lock4 = new ReentrantLock4();
- new Thread(()->lock4.m1(),"t1").start();
- new Thread(()->lock4.m1(),"t2").start();
- }
- }
5.使用wait和notifyAll实现消费者生产者模式
- package com.dingyu2;
- import java.util.LinkedList;
- /**
- * 使用wait和notifyAll实现消费者生产者模式
- *
- * @author dingyu
- *
- */
- public class ProduceConsumer {
- private final LinkedList<Integer> lists = new LinkedList<Integer>();
- private final int MAX = 10;
- private int count = 0;
- public synchronized void put(Integer i) {
- while (lists.size() == MAX) { // wait大多数情况和while一起用
- try {
- this.wait();// 如果满了我就释放锁,并且等待
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- lists.add(i);// 生产一个
- count++;
- this.notifyAll();// 叫醒消费者可以消费啦
- }
- public synchronized Integer get() {
- while (lists.size() == 0) {
- try {
- this.wait();// 如果集合为空,不能消费,释放锁,等着
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- Integer num = lists.removeFirst();
- count--;
- this.notifyAll();// 叫醒生产者,可以继续生产啦
- return num;
- }
- }
6.使用Condition 完成生产者消费者模式
- package com.dingyu2;
- /**
- * 使用Condition 完成生产者消费者模式
- * @author dingyu
- *
- */
- import java.util.LinkedList;
- import java.util.concurrent.locks.Condition;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- public class ProduceConsumer2 {
- private final LinkedList<Integer> lists = new LinkedList<Integer>();
- private final int MAX = 10;
- private int count = 0;
- private Lock lock = new ReentrantLock();
- private Condition p = lock.newCondition();// 生产者
- private Condition c = lock.newCondition();// 消费者
- public void put(Integer i) {
- try {
- lock.lock();
- while (lists.size() == MAX) {
- try {
- p.await();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- lists.add(i);
- count++;
- c.signalAll();
- } finally {
- lock.unlock();
- }
- }
- public Integer get() {
- Integer i = null;
- try {
- lock.lock();
- while (lists.size() == 0) {
- try {
- c.await();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- i = lists.removeFirst();
- count++;
- p.signalAll();
- } finally {
- lock.unlock();
- }
- return i;
- }
- }
7.ThreadLocal 线程局部变量 每个线程中的这个变量归自己线程管
- package com.dingyu;
- public class ThreadLocal1 {
- private ThreadLocal<Integer> tl = new ThreadLocal<Integer>();
- public void m1() {
- System.out.println(tl.get());
- }
- public void m2() {
- tl.set(7898);
- }
- public static void main(String[] args) {
- ThreadLocal1 local1 = new ThreadLocal1();
- new Thread(() -> local1.m2()).start();
- try {
- Thread.sleep(5000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- new Thread(() -> local1.m1()).start();
- }
- }
Java马士兵高并发编程视频学习笔记(二)的更多相关文章
- Java马士兵高并发编程视频学习笔记(一)
1.同一个资源,同步和非同步的方法可以同时调用 package com.dingyu; public class Y { public synchronized void m1() { System. ...
- 《Java虚拟机并发编程》学习笔记
对<Java虚拟机并发编程>这本书真的是相见恨晚.以前对并发编程只是懂个皮毛,这本书让我对并发编程有了一个全新的认识.所以把书上的知识点做下笔记,以便以后复习使用. 并发与并行 仔细说来, ...
- java 多线程——并发编程模型 学习笔记
并发编程模型 ...
- Java并发编程实战 读书笔记(二)
关于发布和逸出 并发编程实践中,this引用逃逸("this"escape)是指对象还没有构造完成,它的this引用就被发布出去了.这是危及到线程安全的,因为其他线程有可能通过这个 ...
- 《Java并发编程的艺术》第4章 Java并发编程基础 ——学习笔记
参考https://www.cnblogs.com/lilinzhiyu/p/8086235.html 4.1 线程简介 进程:操作系统在运行一个程序时,会为其创建一个进程. 线程:是进程的一个执行单 ...
- 《实战Java高并发程序设计》读书笔记二
第二章 Java并行程序基础 1.线程的基本操作 线程:进程是线程的容器,线程是轻量级进程,是程序执行的最小单位,使用多线程而不用多进程去进行并发程序设计是因为线程间的切换和调度的成本远远的小于进程 ...
- Go语言并发与并行学习笔记(二)
转:http://blog.csdn.net/kjfcpua/article/details/18265461 Go语言的并发和并行 不知道你有没有注意到一个现象,还是这段代码,如果我跑在两个goro ...
- java高并发编程(一)
读马士兵java高并发编程,引用他的代码,做个记录. 一.分析下面程序输出: /** * 分析一下这个程序的输出 * @author mashibing */ package yxxy.c_005; ...
- Java 面试知识点解析(二)——高并发编程篇
前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...
随机推荐
- 一次 Java 内存泄漏的排查
由来 前些日子小组内安排值班,轮流看顾我们的服务,主要做一些报警邮件处理.Bug 排查.运营 issue 处理的事.工作日还好,无论干什么都要上班的,若是轮到周末,那这一天算是毁了. 不知道是公司网络 ...
- 2019-4-29 js学习笔记
js学习笔记一:js数据类型 1:基本数据类型 number类型(整数,小数) String类型 boolean类型 NaN类型其实是一个nu ...
- Android 基本控件相关知识整理
Android应用开发的一项重要内容就是界面开发.对于用户来说,不管APP包含的逻辑多么复杂,功能多么强大,如果没有提供友好的图形交互界面,将很难吸引最终用户.作为一个程序员如何才能开发出友好的图形界 ...
- IntelliJ IDEA 使用前常用设置
0.设置位置 以下设置基于IntelliJ IDEA 2018.3.2 版本. IDEA 的设置一般都在 File 下的 Settings... 里进行设置的. 1.设置字体字号行间距 2.设置背景图 ...
- C++ Opencv HoughLines()用霍夫变换在二元图像中寻线
一.霍夫变换简介 参考http://homepages.inf.ed.ac.uk/rbf/HIPR2/hough.htm 二.HoughLines()函数详解 该函数接受的输入矩阵只能是8位单通道的二 ...
- 第83节:Java中的学生管理系统分页功能
第83节:Java中的学生管理系统分页功能 分页功能一般可以做成两种,一种是物理分页,另一种是逻辑分页.这两种功能是有各自的特点的,物理分页是查询的时候,对数据库进行访问,只是查一页数据就进行返回,其 ...
- 前端切图神器-cutterman
之前我写过一篇关于前端切图的博客:https://www.cnblogs.com/tu-0718/p/9741058.html 但上面的方法在切图量大时依然很费时间,下面向大家推荐这款免费切图神器 c ...
- java后端服务器读取excel将数据导入数据库
使用的是easypoi,官网文档:http://easypoi.mydoc.io/ /** * 导入Excel文件 */ @PostMapping("/importTeacher" ...
- 推荐:7 月份值得一看的 Java 技术干货!
月底了,又到了我们总结这一个月 Java 技术干货的时候了,又到了我们给粉丝免费送书的日子了. 7 月份干货总结 Oracle 发布了一个全栈虚拟机 GraalVM 一文带你深入拆解 Java 虚拟机 ...
- 召回率,精确率,mAP如何计算
首先用训练好的模型得到所有测试样本的confidence score,每一类(如car)的confidence score保存到一个文件中(如comp1_cls_test_car.txt).假设 ...