当前课程知识点:JAVA程序设计进阶 >  第三章 线程(下) >  3.2 线程的安全实现-互斥同步 >  Video

返回《JAVA程序设计进阶》慕课在线视频课程列表

Video在线视频

Video

下一节:Video

返回《JAVA程序设计进阶》慕课在线视频列表

Video课程教案、知识点、字幕

刚才我们已经介绍了

线程安全的概念

那这一节我们将介绍

如何去实现线程安全

那实现线程安全的话有多种方式

那我们今天将介绍

互斥同步 非阻塞同步

无同步方案等三种方式

那第一种实现方式就是互示同步

那我们对同步的话

它在互斥实现的过程当中

可以采用临界区 或者互斥量

或者信号量等方式来进行实现

那这些实现方式

如果大家学过

操作系统课程的话

都可以接触到这些内容

那在我们java当中的话

要实现互斥的话

所采取的方式就是

使用synchronized关键字

那大家在前面学习的过程中

已经多次看到了

这样的这个关键字

那如果你在写

java源代码过程当中

加入synchronized关键字

那我们的java编译器

在编译的时候

就会在我们的同步代码块的前面

加入一个字节码

叫monitorenter

那在同步代码块的最后

加入monitorexit这个字节码

实际上就是

把我们需要同步的这些代码块

分别对它的入口和出口

做了一个标识

这样当我们的这些同步代码块

在执行的时候

就能够被这个java的

运行环境所识别

那这个synchronized同步块

对自己它是可重入的

不会把自己给锁死

那当这些同步块

在进入到线程的执行完成之前

它就会阻塞其他线程的进入

以保证我们这种数据的安全性

实现我们的互斥与同步

那实现互斥同步的话

另外一种方式可以用重入锁

就叫Reentrantlock

那这么这个类的话

是来自于我们java当中的

另外一个包

叫java.util.concurrent这个包

那我们用这个重入锁的话

它相比我们之前用synchronized

这个关键字来说

它的优点是可以实现等待可中断

以及实现公平锁

甚至实现锁去绑定多个条件

这是采用Reentrantlock

这个类的一个好处

那synchronized它表现为

就是原生语法层面的互斥锁

而Reentrantlock

它表现为API层面的互斥锁

下面我们通过这么一个例子

来去告诉大家

这个Reentrantlock

到底是怎么使用的

我们看一下代码第一行

import java.util.concurrent.

locks.reentrantlock这个类

我们看一下

我们定义的类的名字

public class Bufferinterruptibly

在这个类当中有一个成员变量

叫private reentrantkock lock

等于new Reentrantlock

紧接着我们定义

我们这个类的一个方法

叫public vaid write

run方法里面第一行

lock.lock方法

其实这行代码意思就是

我要对我的那个重入锁

Reentrantlock

这个lock对象

我要调用它的加锁功能

就是lock功能

这个功能其实的话

给大家打一个通俗的比方

就比如说你在进入这个

更衣室的时候

你就会把那个锁给锁上

那这时候再进行相应的操作

我们看那个我们下面

进行哪个操作呢

try long startTime

等于System.currentTimeMillis

就是说我要得到当前的这个时间

紧接着我们打印

System.out.println

往这个我们的这个一个缓冲区

去写数据

紧接着我们做了一个无限循环

for这个无限循环

是用来模拟一下这个处理时间

然后我们会在这个循环当中

去判断说如果当前的时间

减掉刚才我们这个

起始时间System

大于某一个预值的时候

那我们这个循环就结束

那我们大于哪个预值呢

就是大于我们Integer

这个类的它的最大值

也就是我们这个整型数

就是这个32位整型数的

它的最大值的时候

我们循环就结束了

结束完以后我们说就打印出来

终于这个往这个缓冲区

写内容的操作写完了

最后finally lock.unlock

这我用红色给它标出来

这时候就把锁打开了

那其实大家看这个例子

实际上是非常通俗易懂

也就是说当你想要执行

你那些代码的时候

你一开头先把锁给锁上

然后你这个代码执行完了以后

你再把锁这个打开

这个就像我刚才给大家举的例子

比如说你去买一幅

你要去一个那个更衣室

去试着衣服

进了这更衣室你把门锁上

然后你把衣服试完挑好以后

你再把这锁打开你就出来

然后这时候这更衣室

就可以继续被别人使用了

所以这个体现了

我们这个程序当中

就是两个操作

一个是lock锁的操作

然后另外一个就是unlock

开锁的这个操作

那再往下的代码

就是它的另外一个方法

叫public void read

读的这个方法 读的方法

那刚才上一个方法是写的方法

那读的方法里面

我们看它的方法体第一行

lock.locklnterruptlbly

也就是说它也是加锁

只不是说我在加锁的时候

这种锁的话还可以响应中断

紧接着我们就

System.out.println

我就打印出来

从这个缓冲区里读数据

finally最后我们lock.unlock

当我们读完了以后

我们就是把它锁打开

所以在这个读的方法里面

我们也是访问了lock这个对象

然后调用了它的这个加锁的方法

叫locklnterruptlbly

也调用它的开锁方法

lock.unlock

那通过这个例子也是想告诉大家

也就是说我们通过重入锁

就是reentrantlock

这个类的对象

我们一样也可以实现

代码之间的这种互斥同步

当然这个两种方法相比

也就是说我们使用重入锁

reentrantlock

和使用同步的关键词

synchronized

对于我们的这个程序的性能方面

会有什么影响呢

这是我们得到的两张

这个性能的这个比较图

每一张图它的这个横坐标

是我们程序运行时候的

这个线程的数量

纵坐标是它的这个

程序的这个吞吐量

那从外边这张图当中

我们可以看到

它是在一个cpu的情况下

运行的性能对比

我们的蓝色的话

是采用了synchronized

这个关键词来进行

修饰的这些程序

这个粉红色的这个线条

是采用这个Reentrantlock

这种方法来进行这个实现的代码

我们可以从性能上来看得出来

用Reentrantlock

这个方法的话

它的这个吞吐率的话

一直还是维持在

比较高的一个状态

对于synchronized的话

它的吞吐率这个下降的比较快

而且也一直维持在

比较低的一个状态

那我们再看一下右边这张图

右边这张图 左边这张图的

不同之处是在于

是这个我们运行的这个电脑

是有四个CPU

那在有四个CPU的情况下

大家应该可以看到

我们的Reentrantlock

这条粉红色的这个线条的话

看到的这个结果

它的这个性能还比较平稳

一直在处于比较高位的这个状态

而用synchronized

这个来修饰的这个程序的话

它这个性能下降也是比较快的

所以从这两张图

大家也可以看到说

当你要实现你的互斥同步的时候

你有多种选择

但是如果你能选择一种

让你的程序性能

更好的一种代码实现方式

将帮助你的程序

取得更好的效果

那这一节内容

我们就介绍到这里

JAVA程序设计进阶课程列表:

第一章 线程(上)

-1.0 导学

--Video

-1.1 线程的基本概念

--Video

-1.1 线程的基本概念--作业

-1.2 通过Thread类创建线程

--Video

-1.2 通过Thread类创建线程--作业

-1.3 线程的休眠

--Video

-1.3 线程的休眠--作业

-1.4 Thread类详解

--Video

-1.5 通过Runnable接口创建线程

--Video

-1.5 通过Runnable接口创建线程--作业

-1.6 线程内部的数据共享

--Video

第二章 线程(中)

-2.0 导学

--Video

-2.1 线程同步的思路

--Video

-2.2 线程同步的实现方式—Synchronization

--Video

-2.3 线程的等待与唤醒

--Video

-2.4 后台进程

--Video

-2.5 线程的生命周期与死锁

--Video

-2.6 线程的调度

--Video

第三章 线程(下)

-3.0 导学

--Video

-3.1 线程安全与线程兼容与对立

--Video

-3.2 线程的安全实现-互斥同步

--Video

-3.3 线程的安全实现-非阻塞同步

--Video

-3.4 线程的安全实现-无同步方案

--Video

-3.5 锁优化

--Video

第四章 网络编程(上)

-4.0 导学

--Video

-4.1 URL对象

--Video

-4.2 URLConnection对象

--Video

-4.3 Get请求与Post请求

--Video

-4.4 Socket通信原理

--Video

-4.5 Socket通信实现

--Video

第五章 网络编程(下)

-5.0 导学

--Video

-5.1 Socket 多客户端通信实现

--Video

-5.2 数据报通信

--Video

-5.3 使用数据报进行广播通信

--Video

-5.4 网络聊天程序

--Video

第六章 Java虚拟机

-6.0 导学

--Video

-6.1 Java虚拟机概念

--Video

-6.2 Java虚拟机内存划分

--Video

-6.3 Java虚拟机类加载机制

--Video

-6.4 判断对象是否存活算法及对象引用

--Video

-6.5 分代垃圾回收

--Video

-6.6 典型的垃圾收集算法

--Video

-6.7典型的垃圾收集器

--Video

第七章 深入集合Collection

-7.0 导学

--Video

-7.1 集合框架与ArrayList

--Video

-7.2 LinkedList

--Video

-7.3 HashMap与HashTable

--Video

-7.4 TreeMap与LinkedHashMap

--Video

-7.5 HashSet

--Video

第八章 反射与代理机制

-8.0 导学

--Video

-8.1 Java反射机制

--Video

-8.2 Java静态代理

--Video

-8.3 Java动态代理

--Video

-8.4 Java 反射扩展-jvm加载类原理

--Video

-8.5 Java进阶课程总结

--Video

Video笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。