JAVA 多线程(1):synchronized
入坑3年,对线程总是一知半解,最多停留在copy,决定还是仔细看看这方面的东西,一点点的记录让自己理解,对一些重要的概念进行记录和理解(包括参考作者的原话与个人理解)
参考链接:https://www.cnblogs.com/wxd0108/p/5479442.html
平行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,我们会用TPS或者QPS来反应这个系统的处理能力。
这个图挺经典的:
concurrent:并发
一个咖啡厅,2队人排队,看谁跑的快,1队和2队是排好的,但是谁抢到就看2队人的身体素质了。(毫无人性可言)
parallel:并行
两个咖啡厅,大家都排队去买,很有顺序的说,至少不会发生打架或争吵。
线程安全:指在并发的情况之下,该代码经过多线程使用,线程的调度顺序不影响任何结果。这个时候使用多线程,我们只需要关注系统的内存,cpu是不是够用即可。反过来,线程不安全就意味着线程的调度顺序会影响最终结果。
一般情况下,如果不涉及事务处理的时候,比如批量导入某个数据表的数据时,如果其中不存在事务关系时,可以不用关心,比如100个人(100个线程)要进厕所等,厕所是公用的,那么大家都可以进去解决一下~ = =
但是公共厕所不是免费的,那就要先买票再进去解决(这里比如厕所类有2个方法,一个是买票,一个是进厕所~ = =),大家都要先去买票,票的价格按顺序增加,第一个人是1块,第二人是2块,那么如果100个人都同时去买票,可能100个人会同时买到票(也有可能
有前后),那么有可能大家都买到了1块钱的票,然后就都可以去上厕所了,但是买票的亏了啊,本来能赚5050 块钱,结果只收了100块钱~ (可能会有疑问的时候,现实生活中可能只有一个窗口,怎么会出现呢,这里希望不要去纠结这个事情,打个比方,如果也有100个卖票窗口,也希望能卖到5050 块钱的票,怎么办~ 希望看这例子的人能看懂 - - 哈哈)
所以,怎么办~?
要求大家排队,强制要求不能同时买票,只设置一个窗口,或者即使2个窗口,也必须在A窗口卖完之后B窗口才能出票。这样保证100个人一定能卖出5050块钱的票。
也就是要求同步操作,保证调用顺序。
如果保证:加锁
参考地址:https://www.cnblogs.com/wl0000-03/p/5973039.html
synchronized:同步关键字
相关锁知识:
java的内置锁:每个java对象都可以用做一个实现同步的锁,这些锁成为内置锁。线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁。获得内置锁的唯一途径就是进入这个锁的保护的同步代码块或方法。 java内置锁是一个互斥锁,这就是意味着最多只有一个线程能够获得该锁,当线程A尝试去获得线程B持有的内置锁时,线程A必须等待或者阻塞,知道线程B释放这个锁,如果B线程不释放这个锁,那么A线程将永远等待下去。
java的对象锁和类锁:java的对象锁和类锁在锁的概念上基本上和内置锁是一致的,但是,两个锁实际是有很大的区别的,对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的class对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个class对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的
理解:
锁是每个对象都有的,就好像每个房间都没有门一样(假设都有)。但是门上的锁需不需要用又是另一回事,有可能锁都是开开的。
而如果一旦需要用钥匙打开门,那么每个房间就只能有一个人进入,这个人进去后,别人是进不来的,比如只有一个马桶的厕所,别人不能进来~ 只有等那人出来了,第二个人(线程)才能拿到钥匙开开门。
对象锁和类锁:对象锁针对一个类可以有多个,因为对象实例可以有多个,但是的类只有一个class对象。
所以,对象锁针对每个对象实例是互不干扰的,但是类锁会以为着会管理所有的实例。
注意:类锁修饰方法和代码块的效果和对象锁是一样的,因为类锁只是一个抽象出来的概念,只是为了区别静态方法的特点,因为静态方法是所有对象实例共用的,所以对应着synchronized修饰的静态方法的锁也是唯一的,所以抽象出来个类锁。
可以参考这个链接:https://www.cnblogs.com/nn369/p/8043303.html
其中第一个示例里如果把this 改为 Bank.class ,你会看到效果的不同。
同步方法与同步代码块:
public synchronized void produce(){
// TODO
}
同步方法:
针对某个方法进行同步,意味着如果获得获得锁后必须执行完这个方法,才会释放锁,如果里面要处理的东西非常多,会很影响性能。针对高并发有可能会导致系统崩溃,
如果某个线程在同步方法里面发生了死循环,那么它就永远不会释放这个对象锁,那么其他线程就要永远的等待。
同步代码块:
同步代码块会只针对其中某一块代码加锁,这样如果我们把最需要同步的地方加上锁就可以,比如核心运算,这样会降低系统崩溃的风险。
比如一个厕所有1个坑,厕所大家可以都进来(房间不加锁),之前的买票大家可以同时买了,都是1块钱一个人,那么等待坑上那个人(线程)解决之后,下一个人就可以直接上了~ 不用再去票再进来了,这样会提高一些效率,省去买票的时间。
或者说,票还是+1 块钱,这样买完票的可以直接进入房间,也不用非得等到里面的人出来再进入了。(~~)
而且同步代码块可以指定对象锁,就好像只能钥匙一样,不一定是当前对象的内置锁,也可以是其他对象锁。
就比如:厕所门的锁需要去公园管理处拿一样,在厕所门口的售票处是没有这个门的锁的。
JAVA 多线程(1):synchronized的更多相关文章
- Java多线程-同步:synchronized 和线程通信:生产者消费者模式
大家伙周末愉快,小乐又来给大家献上技术大餐.上次是说到了Java多线程的创建和状态|乐字节,接下来,我们再来接着说Java多线程-同步:synchronized 和线程通信:生产者消费者模式. 一.同 ...
- Java多线程同步 synchronized 关键字的使用
代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A, ...
- Java多线程同步方法Synchronized和volatile
11 同步方法 synchronized – 同时解决了有序性.可见性问题 volatile – 结果可见性问题 12 同步- synchronized synchronized可以在任意对象上加 ...
- Java多线程:synchronized的可重入性
从Java多线程:线程间通信之volatile与sychronized这篇文章中我们了解了synchronized的基本特性,知道了一旦有一个线程访问某个对象的synchronized修饰的方法或代码 ...
- java 多线程8 : synchronized锁机制 之 方法锁
脏读 一个常见的概念.在多线程中,难免会出现在多个线程中对同一个对象的实例变量或者全局静态变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数 ...
- Java 多线程之 synchronized 和 volatile 的比較
概述 在做多线程并发处理时,常常须要对资源进行可见性訪问和相互排斥同步操作.有时候,我们可能从前辈那里得知我们须要对资源进行 volatile 或是 synchronized 关键字修饰处理.但是,我 ...
- 四、java多线程核心技术——synchronized同步方法与synchronized同步快
一.synchronized同步方法 论:"线程安全"与"非线程安全"是多线程的经典问题.synchronized()方法就是解决非线程安全的. 1.方法内的变 ...
- 关于JAVA多线程并发synchronized的测试与合理使用
在项目开发中, 或许会碰到JAVA的多线程处理, 为保证业务数据的正常, 必须加上锁机制, 常用的处理方法一般是加上synchronized关键字, 目前JDK版本对synchronized已经做了 ...
- java多线程中synchronized关键字的用法
转自:http://www.cdtarena.com/javapx/201308/9596.html 由于同一进程内的多个线程共享内存空间,在Java中,就是共享实例,当多个线程试图同时修改某个实例的 ...
- Java多线程:synchronized关键字和Lock
一.synchronized synchronized关键字可以用于声明方法,也可以用来声明代码块,下面分别看一下具体的场景(摘抄自<大型网站系统与Java中间件实践>) 案例一:其中fo ...
随机推荐
- Java面试集合(四)
1. jdk,jre,jvm之间的关系 JVM是Java虚拟机,是Java跨平台的重要保障,JVM实现Java跨平台的前提,可以针对不同的操作系统,有不同的JVM. 可以说Java语言是跨平台的,但J ...
- 性能瓶颈之Target
最常见的性能问题都发生在向目标数据库写数据的时候 常见的与目标数据库性能有关的问题有: 1) 数据库的checkpoint间隔太小 2) 数据库网络包太小 3) 在进行大批量数据加载时的问题 ...
- vis.js没有中文文档,个人在项目中总结的一些中文配置
##vis.js var options = { nodes:{//节点配置 borderWidth: 1,//节点边框的宽度,单位为px borderWidthSelected: 2,节点被选中时边 ...
- 整理+学习《骆昊-Java面试题全集(中)》
这部分主要是与Java Web和Web Service相关的面试题. 96.阐述Servlet和CGI的区别? 答:Servlet与CGI的区别在于Servlet处于服务器进程中,它通过多线程方式运行 ...
- Spring Boot到底是怎么运行的,你知道吗?
导读 Spring Boot方式的项目开发已经逐步成为Java应用开发领域的主流框架,它不仅可以方便地创建生产级的Spring应用程序,还能轻松地通过一些注解配置与目前比较流行的微服务框架Spring ...
- 关于vue2.0+hbuilder打包移动端app之后空白页面的解决方案
楼主是使用vue-cli构建的页面,代码是vscode,然后使用hbuilder打包成移动端的安装包.首先确认在npm run build 之后没有问题(默认dist文件夹),可以使用anywhere ...
- springBoot(4)---热部署,配置文件使用
热部署,配置文件使用 一.热加载 spring为开发者提供了一个名为spring-boot-devtools的模块来使Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Sprin ...
- mysql 开发基础系列19 触发器
触发器是与表有关的数据库对象,触发器只能是针对创建的永久表,而不能是临时表. 1.1 创建触发器 -- 语法: CREATE TRIGGER trigger_name trigger_time tri ...
- XSS和CSRF
说到XSS这个问题,XSS又叫跨站请求攻击,大意是说比如我发表了一篇博客,然后我在自己博客里面插入了一段恶意的js脚本代码,这段代码用于获取当前用户的cookie,并发送到我的服务器,当你们在看到这篇 ...
- [NewLife.XCode]增量累加
NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netstandard,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示 ...