浅谈synchronized
浅谈synchronized
前言
看多线程的相关书籍的时候,会经常阅读到一个使用前景,就是银行的取钱存钱操作。
假设我们使用两个线程来模拟取钱操作,模拟两个人使用同一个账户并发取钱的问题,我们都知道存款不可能为负的,
但是往往并发操作的时候,可能就会导致系统出错导致出现负的数字(假设一开始都是200元余额,两边同时操作取出150,系统可能就会出错)。
出现类似这种问题就是缺少同步安全性,为了解决这个问题,Java就增进了同步监视器来解决这个,也就是本文讲的synchronized的作用。
是什么
synchronized是Java中的关键字。同步的意思,用在解决线程安全问题上。有添加在方法上,和直接修饰代码块。有种保护的作用,使用修饰之后,家门上了锁,别人进不来。用synchronized修饰的方法只允许一个线程执行,其他线程无法进入该方法。(原子性操作),银行使用该操作之后,就会变成一个排队操作一样,像前言的例子,就会变成一个人等另一个操作取出150之后才可以取钱,这样就不会出现负的余额。
- 基本上所有的并发模式 在解决线程冲突的时候,都是采用序列化访问共享资源的方案。就是在给定的时间间隔内只允许一个任务访问共享资源。
所以synchronized保护的是线程遭受破坏,必须按照允许的权限进行资源访问。
记得synchronized关键字可以修饰方法,可以修饰代码块,但不能修饰构造函数、属性等。
//long与double的操作不是原子的

格式

同步代码块
//synchronized代码块
//obj对象即表示线程开始执行同步代码块之前,必须先获得对同步监视器的锁定
//步骤:加锁--修改--释放锁
synchronized (obj) {
...
}
任何时刻只能有一个线程可以获得对同步监视器的锁定,当同步代码块执行完成后,该线程会释放对该同步监视器的锁定。具体的格式参见上面。
同步方法
//synchronized方法,可以分为静态方法和普通方法
synchronized void method(){
...
}
//等价于
public void method()
{
synchronized(this) {
// todo
}
}
//无论哪种形式都可以看做是“{”处获取锁,“}”释放锁
与同步代码块对应,Java 的多线程安全支持还提供了同步方法,同步方法就是使用synchronized关键字来修饰某个方法(放在权限词的后面即可),则该方法称为同步方法。对于同步方法而言,无须显式指定同步监视器,同步方法的同步监视器是this,也就是该对象本身。在格式上可以看到一些用法,但是具体来讲,synchronized用在方法体上还分为用在普通方法和静态方法两种,区别在作用锁对象的不同。
修饰普通方法作用的是调用这个方法的对象,修饰静态方法作用是调用这个类的所有对象。
synchronized static方法可以在类的范围内防止对static数据的并发访问,
使用同步方法可以很方便得实现线程安全的类,这样类的对象可以被多个线程同时安全得访问。
注意
- synchronized不能被继承。
- collection中的线程不安全的集合可以变成使用Collections工具类的,具体用法语句可以参考API文档,写的还算比较详细。

最后
关于什么使用同步,也就是上锁,引用书上的话
如果你在写一个变量,它可能接下来将被另一个线程读取,或者正在读取上一个已经被另一个线程写过的变量,那么你必须使用同步,并且,读取线程都必须用相同的监视器锁同步
——Brain Goetz《Java Concurrency in Pactice》的作者
个人学习记录,有错误欢迎指点,谢谢!加油!
浅谈synchronized的更多相关文章
- Java多线程编程(四)—浅谈synchronized与lock
一.共享资源竞争问题 在Java语言的并发编程中,由于我们不知道线程实际上在何时运行,所以在实际多线程编程中,如果两个线程访问相同的资源,那么由于线程运行的不确定性便会在这种多线程中产生访问错误.所以 ...
- 浅谈synchronized和volatitle实现线程安全的策略
什么是线程不安全 我对线程安全的理解就是多个线程同时操作一个共享变量时会产生意料之外的情况,这种情况就是线程不安全.注意:只有写操作才可能出现线程不安全,对共享变量只进行读操作线程是绝对安全的. 具体 ...
- 对kotlin和java中的synchronized的浅谈
synchronized在java中是一个关键字,但是在kotlin中是一个内联函数.假如分别在java和kotlin代码锁住同一个对象,会发生什么呢,今天写了代码试了试.首先定义people类 12 ...
- 浅谈 LayoutInflater
浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...
- 谁还没遇上过NoClassDefFoundError咋地——浅谈字节码生成与热部署
谁还没遇上过NoClassDefFoundError咋地--浅谈字节码生成与热部署 前言 在Java程序员的世界里,NoClassDefFoundError是一类相当令人厌恶的错误,因为这类错误通常非 ...
- 浅谈Java线程安全
浅谈Java线程安全 - - 2019-04-25 17:37:28 线程安全 Java中的线程安全 按照线程安全的安全程序由强至弱来排序,我们可以将Java语言中各种操作共享的数据分为以下五类 ...
- Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理
Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理 转自:https://www.jianshu.com/p/2b71ea919d49 本系列文章首发于我的个人博 ...
- 浅谈iOS多线程
浅谈iOS多线程 首先,先看看进程和线程的概念. 图1.1 这一块不难理解,重点点下他们的几个重要区别: 1,地址空间和资源:进程可以申请和拥有系统资源,线程不行.资源进程间相互独立,同一进程的各线程 ...
- 浅谈SpringBoot核心注解原理
SpringBoot核心注解原理 今天跟大家来探讨下SpringBoot的核心注解@SpringBootApplication以及run方法,理解下springBoot为什么不需要XML,达到零配置 ...
随机推荐
- 21.python的模块(Module)和包(Package)
目录 模块(Module)和包(Package) 模块(modue)的概念 模块导入方法 1.import 语句 2.from-import 语句 3.from-import* 语句 4.运行本质 i ...
- 小白学 Python 爬虫(30):代理基础
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 在 Win7、Win10 家庭版中启用组策略(gpedit.msc)
Windows 家庭版并没有组策略,对于计算机维护.优化和设置非常不方便.使用以下批处理可以在不安装专业版.旗舰版的情况下启用组策略. 一.新建一个批处理脚本 1 @echo off 2 3 push ...
- 一文详解滑动平均法、滑动平均模型法(Moving average,MA)
任何关于算法.编程.AI行业知识或博客内容的问题,可以随时扫码关注公众号「图灵的猫」,加入”学习小组“,沙雕博主在线答疑~此外,公众号内还有更多AI.算法.编程和大数据知识分享,以及免费的SSR节点和 ...
- apache相关实验-1
一.目录别名实验 当 apache 接受请求时,在默认情况下会将 DocumentRoot 目录中的文件送到客户端,如果想将某一不在 DocumentRoot 目录中的文件共享到网站上,并希望将它们留 ...
- 洛谷P1082 同余方程 题解
题目链接:https://www.luogu.com.cn/problem/P1082 题目大意: 求关于 \(x\) 的同余方程 ax≡1(mod b) 的最小正整数解. 告诉你 \(a,b\) 求 ...
- 「P5004」专心OI - 跳房子 解题报告
题面 把\(N\)个无色格子排成一行,选若干个格子染成黑色,要求每个黑色格子之间至少间隔\(M\)个格子,求方案数 思路: 矩阵加速 根据题面,这一题似乎可以用递推 设第\(i\)个格子的编号为\(i ...
- js中getBoundingClientrRect()方法的详解
getBoundingClientRect(): 这个方法返回一个矩形对象,包含四个属性:left.top.right和buttom.分别表示元素各边与页面各边的距离 例如: var boxPosit ...
- X-Admin&ABP框架开发-租户管理
软件即服务概念的推动,定制化到通用化的发展,用一套代码完成适应不同企业的需求,利用多租户技术可以去做到这一点.ABP里提供了多租户这一概念并且也在Zero模块中实现了这一概念. 一.多租户的概念 单部 ...
- 【JavaScript学习笔记】函数、数组、日期
一.函数 一个函数应该只返回一种类型的值. 函数中有一个默认的数组变量arguments,存储着传入函数的所有参数. 为了使用函数参数方便,建议给参数起个名字. function fun1(obj, ...