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 ...
随机推荐
- HDU4421 Bit Magic 【2-sat】
叙述性说明: 这给出了一个矩阵,原来的请求a排列 2-sat称号.对于每一位跑步边,跑31位可 详细的施工方 注意N=1的情况特判,还有检查对称元素是否同样 #include <stdio.h& ...
- WPF MessageBox 添加确认取消按钮 并判断
很简单的功能随笔 if (System.Windows.MessageBox.Show("您确定要删除吗?", "提示:", MessageBoxButton. ...
- IOS开发之把 JSON 数据转化成 Arrays 或者 Dictionaries
1 前言通过 NSJSONSerialization 这个类的 JSONObjectWithData:options:error:方法来实现,把JSON 数据解析出来放在数据或者字典里面保存. 2 代 ...
- Spring 中 CharacterEncodingFilter 失效?
# 问题 Spring 提供了CharcterEncodingFilter,专门解决字符串编码的问题. 诡异的是,在类 AbstractAnnotationConfigDispatcherServle ...
- 将QuickReport报表保存为图片(使用TMetaFile和TMetafileCanvas)
//将报表第iPageNo页存为BMP文件 procedure ReportSaveToBMPFile(sFileName :string; iPageNo :integer) ...
- wpf 路由事件 代码片段
<?xml version="1.0" encoding="utf-8" ?> <CodeSnippets xmlns="http: ...
- Java Date Calendar DateFormat Details
From https://www.ntu.edu.sg/home/ehchua/programming/java/DateTimeCalendar.html Date and Time - Creat ...
- Delphi用Socket API实现路由追踪
Windows自带的Tracert是向远程主机发送ICMP包进行追踪,但是目前很多主机关闭了ICMP答复,这个工具不太好使了~~~~~原理咱知道,正规的Trace不就是发送TTL依次递增的UDP包吗? ...
- mqtt消息推送
https://github.com/wizinfantry/delphi-mqtt-clienthttps://github.com/Indemsys/Delphi_MQTT_mosquittoht ...
- C++的 RTTI 观念和用途(非常详细)
自从1993年Bjarne Stroustrup [注1 ]提出有关C++ 的RTTI功能之建议﹐以及C++的异常处理(exception handling)需要RTTI:最近新推出的C++ 或多或少 ...