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 知识点进行复习和学习一番,大 ...
随机推荐
- SQL Server 深入解析索引存储(非聚集索引)
标签:SQL SERVER/MSSQL SERVER/数据库/DBA/索引体系结构/非聚集索引 概述 非聚集索引与聚集索引具有相同的 B 树结构,它们之间的显著差别在于以下两点: 基础表的数据行不按非 ...
- 于bugku中游荡意外得到关于CBC翻转攻击思路
个人简介:渣渣一枚,萌新一个,会划水,会喊六六今天在bugku遇到关于CBC翻转攻击的题目,总结了一下关于CBC翻转攻击的原理,以及关于这道题目的解题思路个人博客:https://www.cnblog ...
- C/C++ 多线程机制
一.C/C++多线程操作说明 C/C++多线程基本操作如下: 1. 线程的建立结束 2. 线程的互斥和同步 3. 使用信号量控制线程 4. 线程的基本属性配置 在C/C++代码编写时,使用多线程机制, ...
- C++ 知识回顾总结 -- 指针
指针是一种特殊类型的变量,用于存储值的地址,因此,指针名表示的是地址.*运算符被成为间接值或解除引用运算符,将其应用于指针,可以得到该地址存储的值. 对指针的理解可以参照以下的例子: #include ...
- 第80节:Java中的MVC设计模式
第80节:Java中的MVC设计模式 前言 了解java中的mvc模式.复习以及回顾! 事务,设置自动连接提交关闭. setAutoCommit(false); conn.commit(); conn ...
- Python开发爆破字典
这里只是分享一下Python如何生成爆破字典 关于爆破工具编写我会在下一篇提到 其实有了爆破字典的话,直接使用Burp,Hydra等一些工具就可以做爆破了! Burp的使用在我以前的博客中有写过,至于 ...
- 剑指offer【06】- 旋转数组的最小数字(java)
题目:旋转数组的最小数字 考点:查找和排序 题目描述:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4, ...
- mysql 架构篇系列 3 复制运行状态监控与选项参数说明
一. 概述 在上一篇中,搭建了一主一从的复制架构,这篇通过一些诊断方法来了解复制的运行状态和一些选项参数说明.上次mysql主从服务关机,今天在打开mysql服务,出现了错误信息. 1.首先 启动主从 ...
- Thrift 基于zookeeper改造模式
对于Thrift服务化的改造,主要是客户端,可以从如下几个方面进行: 1.服务端的服务注册,客户端自动发现,无需手工修改配置,这里我们使用zookeeper,但由于zookeeper本身提供的客户端使 ...
- thinkphp自动创建数据对象分析
thinkphp有一个自动创建数据对象的create方法,核心代码如下 public function create($data='',$type='') { // 如果没有传值默认取POST数据 i ...