Java多线程(2)线程锁
多线程访问同一个资源进行读写操作,就很容易出一些问题(比如我们常见的读者写者,生产者消费者模型)所以我们会选择对他们设置信号量或者加锁,来限制同一个时刻只有一个线程对某个对象进行操作。
多线程是一个蛮复杂的工作,锁加多了就算是看伪代码有的时候脑子都转不过来,所以不要随便加锁(如果对自己的脑子没太多自信的话
Synchronized
Synchronized关键字的作用是实现线程间的同步,它就像我们用PV原语来解决进程互斥问题,然后用对象的wait(),notify()提供线程的同步功能。
它的使用场景如下:
| 分类 | 具体方法 | 被锁的对象 | 伪代码 |
|---|---|---|---|
| 方法 | 实例方法 | 实例对象 | public synchronized void method(){}; //实例方法,锁住的是实例对象 |
| 方法 | 静态方法 | 类对象 | public static synchronized void method(){}; //静态方法,锁住的是类对象 |
| 代码块 | 实例对象 | 类的实例对象 | synchronized(this){...};//同步代码块,锁住的是该类实例对象 |
| 代码块 | class对象 | 类的实例对象 | synchronized(SynchronizedDemo.class){...}; //同步代码块,锁住的是该类的类对象 |
| 代码块 | 任意实例对象Object | 类的实例对象Object | String lock=" "; synchronized(lock){...}; //同步代码块,锁住的是配置的实例对象 |
Attention:如果锁住的是类对象的话,不论new多少个实例出来,因为他们是属于一个类的,所以都会被锁住,保证进程间同步。
从OS的原理上理解,很明显的通过这种方式来依次排队操作共享资源的方式是比较效率低下的。这并不是一个一个非常好的同步机制,但是它是其他并发容器的基础。
Synchronized是怎么实现同步的呢
在学OS的时候,有一章一直在讲PV原语,Proberen申请资源信号量-1,Verhogen释放资源信号量+1(Dijkstra是荷兰人,所以就这么任性的用荷兰语),PV的题目都快做吐了,但是其实在真正的现代OS环境和Java当中,并不是这样简单的来解决问题的。
在Synchronized关键字的机制里面,每个对象拥有一个monitor(计数器),当线程获取该对象锁后,计数器就会加一,释放锁后就会将monitor减一。(为什么你和PV操作刚好相反啊!)
Disadvantage:
由于我们没办法设置synchronized关键字在获取锁的时候等待时间,所以synchronized可能会导致线程为了加锁而无限期地处于阻塞状态。
使用synchronized关键字等同于使用了互斥锁,即其他线程都无法获得锁对象的访问权。这种策略对于读多写少的应用而言是很不利的,因为即使多个读者看似可以并发运行,但他们实际上还是串行的,并将最终导致并发性能的下降。
因为时间片的轮转,导致我们在使用上觉得连贯,在一个时间周期里面看起来像是并发进行(针对单核process而言),但实际上,效率并不高。
Q: Synchronized关键字和lock是一样的吗?它们的区别是什么?
我觉得这两个是不同的概念,但是我的一些同学在开发过程中把Synchronize也叫做锁,一般说加一个对象锁。(虽然觉得不对但是也找不到什么反驳的理由.jpg)
看了一些博客和书之后发现,对象锁知识synchronized在实现锁机制中的一类,它其实有偏向锁,轻量锁,自旋锁等等,所以其实synchronized是一个锁的封装。
关于进程的五状态图这里就不画了,几个状态的切换。值得注意的是,线程在wait()的时候是会释放对象的锁的,而sleep()或者yield()是不会的。
练手的Demo(使用semaphore信号量解决读者写者问题)
https://github.com/JhinQaQ/ReadAndWrite
参考
《Operating Systems : Design and Implementation》
《Java并发编程的艺术》
《实战Java高并发程序设计》
让你彻底理解Synchronized https://www.jianshu.com/p/d53bf830fa09
synchronized的两大不足 http://swiftlet.net/archives/3010
synchronized、锁、多线程同步的原理是咋样的 https://www.jianshu.com/p/5dbb07c8d5d5
Java多线程(2)线程锁的更多相关文章
- Java多线程系列--“JUC锁”03之 公平锁(一)
概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...
- Java多线程系列--“JUC锁”04之 公平锁(二)
概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...
- Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例
概要 本章介绍JUC包中的CyclicBarrier锁.内容包括:CyclicBarrier简介CyclicBarrier数据结构CyclicBarrier源码分析(基于JDK1.7.0_40)Cyc ...
- Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock
本章对ReentrantLock包进行基本介绍,这一章主要对ReentrantLock进行概括性的介绍,内容包括:ReentrantLock介绍ReentrantLock函数列表ReentrantLo ...
- Java多线程系列--“JUC锁”01之 框架
本章,我们介绍锁的架构:后面的章节将会对它们逐个进行分析介绍.目录如下:01. Java多线程系列--“JUC锁”01之 框架02. Java多线程系列--“JUC锁”02之 互斥锁Reentrant ...
- Java多线程系列--“JUC锁”09之 CountDownLatch原理和示例
概要 前面对"独占锁"和"共享锁"有了个大致的了解:本章,我们对CountDownLatch进行学习.和ReadWriteLock.ReadLock一样,Cou ...
- Java多线程系列--“JUC锁”06之 Condition条件
概要 前面对JUC包中的锁的原理进行了介绍,本章会JUC中对与锁经常配合使用的Condition进行介绍,内容包括:Condition介绍Condition函数列表Condition示例转载请注明出处 ...
- Java多线程系列--“JUC锁”05之 非公平锁
概要 前面两章分析了"公平锁的获取和释放机制",这一章开始对“非公平锁”的获取锁/释放锁的过程进行分析.内容包括:参考代码获取非公平锁(基于JDK1.7.0_40)释放非公平锁(基 ...
- Java多线程系列--“JUC锁”07之 LockSupport
概述 本章介绍JUC(java.util.concurrent)包中的LockSupport.内容包括:LockSupport介绍LockSupport函数列表LockSupport参考代码(基于JD ...
- Java多线程系列--“JUC锁”08之 共享锁和ReentrantReadWriteLock
概要 Java的JUC(java.util.concurrent)包中的锁包括"独占锁"和"共享锁".在“Java多线程系列--“JUC锁”02之 互斥锁Ree ...
随机推荐
- ios-利用键盘通知处理键盘出现时遮挡控件问题
-(void)viewDidLoad { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; //注册键盘显示通知 ...
- docker include not found: networks
启动clickhouse的docker镜像时,出现了以下错误 include not found: networks google之后发现是因为可能不支持ipv6导致的解决方法 就是通过设置 /etc ...
- CentOS 7.3最小系统安装KVM
一.准备工作 安装wget和vim yum install -y wget vim 修改yum源为阿里源 wget -O /etc/yum.repos.d/CentOS-Base.repo http: ...
- WPF 代码实现动画
<Window x:Class="wpf180709.Window2" xmlns="http://schemas.microsoft.com/win ...
- WPF 自定义范围分组
<Window x:Class="ViewExam.MainWindow" xmlns="http://schemas.microsoft.com/w ...
- jquery表单过滤器
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- 通通玩blend美工(7)——简约而不简单的块
原文:通通玩blend美工(7)--简约而不简单的块 最近在研发一个WPF快速开发框架,满脑子都是各种逻辑各种模式,写一篇比较休闲娱乐的博客,宣泄下我对美工的热爱. 我一直以来有意无意在手机应用或者各 ...
- 深入理解Amazon Alexa Skill(二)
理解skill调用 本节来更详细的讨论alexa是如何确定调用哪个skill的. 参考:https://developer.amazon.com/zh/docs/custom-skills/under ...
- 图像滤镜艺术---挤压(Pinch)滤镜
原文:图像滤镜艺术---挤压(Pinch)滤镜 Pinch滤镜 Pinch滤镜是通过坐标变换来实现以某个点(cenX,cenY)为中心,某个半径R内图像向其挤压变形的效果.实现这个滤镜的算法很多,主要 ...
- WPF显示html的几种方法
原文:WPF显示html的几种方法 客户希望系统在一些特定的条件下,界面上能显示用户自定义的格式和内容,格式和内容通过html指定. 基本上在wpf中显示html有以下四种方法. 1. W ...