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 ...
随机推荐
- Visual Studio 开发(二):VS 2017配置FFmpeg开发环境
在上篇文章Visual Studio 开发(一):安装配置Visual Studio Code 中,我们讲了一下如何配置VS CODE,来编写和调试C的代码.如果你已经使用VS Code回顾和复习好C ...
- Spark基础-scala学习(三、Trait)
面向对象编程之Trait trait基础知识 将trait作为接口使用 在trait中定义具体方法 在trait中定义具体字段 在trait中定义抽象字段 trait高级知识 为实例对象混入trait ...
- ubuntu下opencv的版本切换及遇到的问题解决
默认使用opencv 3.2的时候,使用SVM的时候,系统报错如下: error: ‘class MySVM’ has no member named ‘decision_func’ 解决方法:要把系 ...
- ubuntu双网卡配置,实现内网外网同时访问!
我们假定内网IP为:10.35.0.58,内网网关为:10.35.0.254:外网IP为222.76.250.4,外网网关为:222.76.250.1.其中局域名网需要连接:10.35.0.X,10. ...
- Linux 系统下实践 VLAN
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 01 准备环境 ...
- 手动实现一个虚拟DOM算法
发现一个好文:<深度剖析:如何实现一个 Virtual DOM 算法> 源码 文章写得非常详细,仔细看了一遍代码,加了一些注释.其实还有有一些地方看的不是很懂(毕竟我菜qaq 先码 有时间 ...
- ES6 块级作用域
作用域包括:全局作用域,函数作用域,块级作用域. 为什么要用块级作用域: 1.内层变量可能会覆盖外层变量. var name = "kevin"; function call() ...
- MapReduce实现ReduceSideJoin操作
本文转载于:http://blog.csdn.net/xyilu/article/details/8996204 一.准备两张表以及对应的数据 (1)m_ys_lab_jointest_a(以下简称表 ...
- 在vue 中使用 less
1.安装 npm install --save-dev less less-loader npm install --save-dev style-loader css-loader 先在index. ...
- HPE服务器做raid5阵列
HPE服务器做阵列的详细步骤: 注意:HPE服务器加硬盘需要安装配套的扩展笼~~~ 1.首先服务器开机,出现下图界面按F10. 2.然后在下图中选择HPE interlligent Provision ...