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 ...
随机推荐
- 【shiro】(4)---Shiro认证、授权案例讲解
Shiro认证.授权案例讲解 一.认证 1. 认证流程 2.用户密码已经加密.加盐的用户认证 (1)测试类 // 用户登陆和退出,这里我自定了一个realm(开发肯定需要自定义realm获取 ...
- Work Queues
Round-robin dispatching 默认情况下,RabbitMQ按顺序分发消息给下一个消费者.平均每个消费者会得到相同数量的消息. Message acknowledgment 为了确保消 ...
- mysql 开发进阶篇系列 49 表的数据导出(into outfile,mysqldump)
一.概述 在数据库的日常维护中,表的导入和导出是很频繁的操作,本篇讲解如何使用导入功能,并以案例为演示.某些情况下,需要将表里的数据导出为某些符号分割的纯数据文本,而不是sql语句,比如:(1)用来作 ...
- 三方面搞定http协议之“请求方法”
我所熟知的请求方法一共有六种: GET 请求指定的页面信息,并返回实体主体. POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件) PUT 从客户端向服务器传送的数据取代指定的文档的内 ...
- leetcode — combination-sum
import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Source : https://o ...
- MFC控件第一讲.DC编程
MFC控件第一讲.DC编程 一丶简介 什么是DC,DC有什么用. DC成为设备描述符表. DC的作用就是可以进行绘制. 比如我们的窗口都是绘制出来的. DC可以简单理解为.没一个窗口程序都有一块内存 ...
- java 学习基础知识点拾遗 导航页
每种编程语言的知识点都是很多很杂的,java也是如此 相信很多人学习的过程中都是深一脚浅一脚,最基础的东西可能有些也不是非常确定 整理了最基本的一些知识点,可以说是java入门的-1层级别的,作为自己 ...
- solr调用lucene底层实现倒排索引源码解析
1.什么是Lucene? 作为一个开放源代码项目,Lucene从问世之后,引发了开放源代码社群的巨大反响,程序员们不仅使用它构建具体的全文检索应用,而且将之集成到各种系统软件中去,以及构建Web应用, ...
- shiro源码篇 - shiro认证与授权,你值得拥有
前言 开心一刻 我和儿子有个共同的心愿,出国旅游.昨天儿子考试得了全班第一,我跟媳妇合计着带他出国见见世面,吃晚饭的时候,一家人开始了讨论这个.我:“儿子,你的心愿是什么?”,儿子:“吃汉堡包”,我: ...
- Hibernate学习(九)———— 二级缓存和事务级别详讲
序言 这算是hibernate的最后一篇文章了,下一系列会讲解Struts2的东西,然后说完Struts2,在到Spring,然后在写一个SSH如何整合的案例.之后就会在去讲SSM,在之后我自己的个人 ...