@Java | Thread synchronized - [ 线程同步锁 基本使用]

对实现了Runnable或者Callable接口类,可以通过多线程执行同一实例的runcall方法,那么对于同一实例中的局部变量(非方法变量)就会有多个线程进行更改或读取,这就会导致数据不一致,synchronized(关键字)可以解决多线程共享数据同步的问题

synchronized使用说明

作用范围

synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
  1. 修饰一个代码块:被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象
  2. 修饰一个非静态方法:被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象
  3. 修改一个静态的方法:其作用的范围是整个静态方法,作用的对象是这个类的所有对象
  4. 修改一个类:其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象
高能提示:
No1 > synchronized修饰的非静态方法:如果一个对象多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,则这个线程所属对象其它线程不能同时访问这个对象任何一个synchronized方法
No2 > synchronized关键字是不能继承的:基类的方法synchronized function(){}在继承类中并不自动是synchronized function(){},而是变成了function(){}。继承类需要你显式的指定它的某个方法为synchronized方法,可以通过子类调用父类的同步方法来实现同步
No3 > 针对synchronized修饰代码块和非静态方法,本质上锁的是代码块或非静态方法对应的对象代码块是synchronized标注的变量,非静态方法是所在类对应的实例),如果是不同的对象是可以同时访问的
No4 > 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制
No5 > 每个对象只有一个锁(lock)与之相关联
No6 > 在定义接口方法时不能使用synchronized关键字
No7 > 构造方法不能使用synchronized关键字,但可以使用synchronized代码块来进行同步

1. 修饰一个代码块

public void syncCode(Object o) {synchronized (o) {// 同步代码块}
}
上面的锁就是o这个对象,当然多个线程同步需要保证o这个对象是同一个,这是有明确的对象作为锁的情况,如果只是想单纯的让某一段代码同步,并没有明确的对象作为锁,可以创建一个特殊的instance变量来充当锁
synchronized(o)修饰的代码块,其中o可以取值一个对象或者一个变量或者this亦或者Clz.class
public class Sync implements Runnable {private byte[] lock = new byte[0];public void syncCode() {synchronized (lock) {// 同步代码块}}public void run ....
}
零长度的byte数组对象创建起来将比任何对象都经济,查看编译后的字节码,生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码

2. 修饰一个非静态方法

public synchronized void method() {// .....}
此时锁的是调用这个同步方法的对象

3. 修饰一个静态方法

public synchronized static void method() {// .....}
synchronized修饰的静态方法锁定的是这个类的所有对象

4. 修饰类

public class Sync implements Runnable {public void syncCode() {synchronized (Sync.class) {// 同步代码块}}public void run ....
}
和作用于静态方法一样,synchronized作用于一个类时,是给这个类加锁,类的所有对象用的是同一把锁

总结

  1. 线程同步的目的是为了保护多个线程反问一个资源时对资源的破坏。
  2. 线程同步方法是通过锁来实现,每个对象都有切仅有一个锁,这个锁与一个特定的对象关联,线程一旦获取了对象锁,其他访问该对象的线程就无法再访问该对象的其他非同步方法
  3. 对于静态同步方法,锁是针对这个类的,锁对象是该类的Class对象。静态和非静态方法的锁互不干预。一个线程获得锁,当在一个同步方法中访问另外对象上的同步方法时,会获取这两个对象锁。
  4. 对于同步,要时刻清醒在哪个对象上同步,这是关键。
  5. 编写线程安全的类,需要时刻注意对多个线程竞争访问资源的逻辑和安全做出正确的判断,对"原子"操作做出分析,并保证原子操作期间别的线程无法访问竞争资源。
  6. 当多个线程等待一个对象锁时,没有获取到锁的线程将发生阻塞。
  7. 死锁是线程间相互等待锁锁造成的,在实际中发生的概率非常的小,一旦程序发生死锁,程序将死掉

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/451677.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 1. 报错: ### Cause: java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符; bad SQL grammar []; nested exception is …

开源代码的使用 二次开发

开源开发,就我的理解,有三种。 1、当作底层基础,使用。例如大家使用mysql就算。有人会认为我说错了。但我认为,开发不代表就是要同一个语言,甚至修改代码。例如我们使用动态库,原先的动态库是什么写的并不重…

Java Application和Java Applet

Java Applet和Java Application 主要区别: (1)运行方式不同。Java Applet程序不能单独运行,它必须依附于一个用HTML语言编写的网页并嵌入其中,通过与Java兼容的浏览器来控制执行。 Java Application是完整的程序&a…

激活prompt

1.下载SQLPrompt 2. 断网, 打开注册机,拷贝验证码 2. 点击activate, 拷贝代码 转载于:https://www.cnblogs.com/zxhome/p/9459415.html

Map 四种获取 key 和 value 值的方法,以及对 map 中的元素排序

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。1. 获取map的值主要有四种方法,分为两类: 调用 map.keySet() 方法来获取 key 和 value 的值; 通…

三、【Map】

主要内容 Map集合 教学目标 能够说出Map集合特点 使用Map集合添加方法保存数据 使用”键找值”的方式遍历Map集合 使用”键值对”的方式遍历Map集合 能够使用HashMap存储自定义键值对的数据 能够使用HashMap编写斗地主洗牌发牌案例 第一章 Map集合 1.1 概述 现实生活中&am…

五种开源协议的比较(BSD,Apache,GPL,LGPL,MIT) – 整理

当Adobe、Microsoft、Sun等一系列巨头开始表现出对”开源”的青睐时,”开源”的时代即将到来! 最初来自:sinoprise.com/read.php?tid-662-page-e-fpage-1.html(遗憾的是这个链接已经打不开了),我基本未改…

[转]自然语言处理中的Attention Model:是什么及为什么

自然语言处理中的Attention Model:是什么及为什么 https://blog.csdn.net/malefactor/article/details/50550211/* 版权声明:可以任意转载,转载时请标明文章原始出处和作者信息 .*/ author: 张俊林 要是关注深度学习在自然语言处理方面…

关西旅游地名读法学习

京都個人旅行ための自己勉強 京都篇 伏見稲荷大社「ふしみいなりだいしゃ」 京都府京都市伏見区深草にある神社。旧称は稲荷神社 全国に約三万社あるといわれる稲荷神社の総本社である。 初詣では近畿地方の社寺で最多の参拝者を集める。(日本第4位)。 清水寺 「き…

jsp页面c标签循环map , c:foreach 循环map

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 <c:forEach items"${customerMap}" var"item"> ${item.code} ${item.name} </c:forEach> map…

JSP上下文

上下文即ServletContext,是一个全局的储存信息的空间&#xff0c;服务器启动&#xff0c;其就存在&#xff0c;服务器关闭&#xff0c;其才释放。所有用户共用一个ServletContext。所以&#xff0c;为了节省空间&#xff0c;提高效率&#xff0c;ServletContext中&#xff0c;要…

python ERROR: Cannot uninstall ‘certifi‘.

解决方法 pip install xxx --ignore-installed certifigithub参考链接

HDU - 6383 百度之星2018初赛B 1004 p1m2(二分答案)

p1m2 Accepts: 1003Submissions: 4595Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 131072/131072 K (Java/Others)Problem Description度度熊很喜欢数组&#xff01;&#xff01;我们称一个整数数组为稳定的&#xff0c;若且唯若其同时符合以下两个条件&#xff1a…

整合营销推广该如何做?

思维方式太重要了&#xff0c;如果你认为你的产品只是推广出去就好&#xff0c;推广就能有销量的话&#xff0c;那你大错特错了。本文主要的分享给创业者和企业老板的&#xff0c;如果你想做好网络营销推广&#xff0c;这篇文章不看是你的损失。 首先记住&#xff1a;推广不等于…

如何使用git命令行上传项目到github

参考文献&#xff1a; 如何使用git命令行上传项目到github 感谢楼主分享&#xff01;

优质的程序员需为代码效率而呕心沥血

一个好的程序员必须要为自己写出来的代码执行效率负责。并非仅仅实现了功能代码就完事了。很多工作一两年的程序员都还仅是处于实现功能代码为荣的阶段&#xff0c;不会过多去思考如何提高代码的执行效率。有的人认为是自己的能力就这样&#xff0c;没有多余的能力去思考这些额…

用gson得JSON,数值变为double类型 ,去掉double值中的小数位(3.0改为3)

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 项目中有个接口的数据是从缓存中读取再组成JSON 格式返出&#xff0c;原本缓存中数据是这样的&#xff1a; 用Gson 组成JSON 后&…

Python中的join()函数的用法

函数&#xff1a;string.join()Python中有join()和os.path.join()两个函数&#xff0c;具体作用如下&#xff1a; join()&#xff1a; 连接字符串数组。将字符串、元组、列表中的元素以指定的字符(分隔符)连接生成一个新的字符串 os.path.join()&#xff1a; 将多个路…