首页 > 编程知识 正文

锁斗程序模式分为哪三种,进程同步的例子

时间:2023-05-03 19:11:56 阅读:163126 作者:2827

1、同步与异步的区别与联系

同步可以理解为执行一个函数或方法后等待系统返回值或消息。 在这种情况下,程序被阻止,因此只有在接收到返回值或消息后才执行其他命令。

异步。 执行函数或方法后,不需要闭塞地等待返回值或消息。 我只需要委托系统进行异步过程。 然后,当系统收到返回值或消息时,将自动启动委托的异步进程,从而完成完整的进程。

在某种程度上,同步可以被视为单线程。 这个线程在请求了一个方法之后,要等待这个方法给他回复。 否则,他不会往下执行。

同步是一件事,就是做每一件事。

异步就是做一件事,不做其他事。 例如,吃饭和说话,只能做一件事。 因为只有一张嘴。 但是,饮食和音乐是异步的。 因为,听音乐不会影响我们的饮食。 对于Java程序员来说,经常听到同步关键字synchronized。 如果此同步是受监视的类,则当一个对象访问类中的同步方法时,其他对象在尝试继续访问类中的同步方法时会进入块,并且在上一个对象执行同步方法后,当前对象才执行该方法这就是同步。 相反,如果方法之前没有同步密钥限定,则不同的对象可以同时访问同一方法是异步的。

补充(脏数据和不能重复的概念) :

脏数据

脏读是指如果一个事务正在访问数据,对数据进行了更改,并且更改尚未提交到数据库,则另一个事务也将访问并使用该数据

个数据。 由于此数据是尚未提交的数据,因此另一事务读取的数据是脏数据,基于脏数据的操作可能不正确。

不能重复

不可重复是指在一个事务中多次读取同一数据。 在此事务未结束期间,另一个事务也会访问相同的数据。 中,对第二个事务的修复可能会导致第一个事务的第二次读取数据在第一个事务的第二次读取数据之间不同。 这样,在一个事务中两次读取的数据就会不同,称为不能重复读取。

2、如何处理并发和同步

在今天的故事中,如何处理并发性和同步性问题主要通过锁定机制来完成。

您需要了解锁定机制有两个层面。

一个是代码级,如java中的同步锁,典型的是同步关键字synchronized。 这里不怎么说明,

感兴趣的朋友可访问:3358 www.cn blogs.com/xio Hao/p/4151408.html

另一个是数据库级别,典型的是悲观锁定和乐观锁定。 这里重点介绍悲观锁(传统的物理锁)和乐观锁。 悲观锁定:

悲观锁定顾名思义,意味着对本系统当前的其他事务以及外部修改数据(包括来自外部系统的事务)持保守态度,因此,在数据处理过程中数据处于锁定状态。 悲观锁定的实现往往依赖于数据库提供的锁定机制。 此外,只有数据库层提供的锁定机制才能真正保证数据访问的排他性。 否则,在本系统中实现锁定机制并不能保证外部系统不会修改数据。 典型的依赖数据库的悲观锁定调用:

slect * fromaccountwherename=" Erica " for update

此sql语句锁定与帐户表中的搜索条件" name=”Erica " "匹配的所有记录。 在提交此事务之前提交事务会导致在事务期间解除锁定。 不能从外部更改这些记录。 乐观锁定:

对于悲观锁定,乐观锁定机制采用了更加宽松的锁定机制。 为了最大限度地确保操作的独占性,悲观锁定往往通过数据库的锁定机制来实现。 但是,这将导致数据库性能的大量开销。 特别是在长事务中,这种开销往往无法承受。 像金融系统一样,某个操作员读取用户数据,基于读取的用户数据进行修改时,例如更改用户账户余额时,采用悲观锁定机制,可以实现操作的全过程(操作员读取数据并开始修改) 甚至包括操作员中途去煮咖啡的时间),数据库记录总是被锁定,在面对数百上千条并发的情况下,这种情况可能的乐观锁定机制在一定程度上解决了这个问题。 乐观锁定往往基于数据版本Version )的记录机制来实现。 什么是数据版本? 这意味着将版本id添加到数据中。 通常,通过在数据库表中添加" version "字段来实现基于数据库表的版本控制解决方案。 读取数据时,一起读出该版本号,然后更新时,在该版本号上加1。 此时,将提交数据的版本数据和数据库表对应记录的当前版本信息进行核对,如果提交数据的版本号大于数据库表的当前版本号,则进行更新,其他情况视为过期数据

3、常见并发同步案例分析

案例:订票系统的案例中,某个航班只有一张票。 假设有1w人打开您的网站订票,询问如何解决并发问题(可以扩展到任何高并发站点都需要考虑的并发读写问题)。 1w人必须访问,在票没有出来之前大家都能看到票。 并不是一个人看到票的时候别人就看不见了。 谁能夺走,是一个人的“运气”(网速等)之后要考虑的问题,同时,1w人同时点击购买,到底谁能成交? 一共只有一张票。 首先,很容易想到与同时性相关的一些方案。 摇滚是一样的

步同步更多指的是应用程序的层面,多个线程进来,只能一个一个的访问,java 中指的是 syncrinized 关键字。锁也有2个层面,一个是 java 中谈到的对象锁,用于线程同步;另外一个层面是数据库的锁;如果是分布式的系统,显然只能利用数据库端的锁来实现。假定我们采用了同步机制或者数据库物理锁机制,如何保证 1w 个人还能同时看到有票,显然会牺牲性能,在高并发网站中是不可取的。使用hibernate后我们提出了另外一个概念:乐观锁、悲观锁(即传统的物理锁);采用乐观锁即可解决此问题。乐观锁意思是不锁定表的情况下,利用业务的控制来解决并发问题,这样即保证数据的并发可读性又保证保存数据的排他性,保证性能的同时解决了并发带来的脏数据问题。hibernate中如何实现乐观锁:前提:在现有表当中增加一个冗余字段,version版本号,long类型。
原理:
1)只有当前版本号 =数据库表版本号,才能提交
2)提交成功后,版本号version ++
案例二、股票交易系统、银行系统,大数据量你是如何考虑的
首先,股票交易系统的行情表,每几秒钟就有一个行情记录产生,一天下来就有(假定行情3秒一个)股票数量×20×60*6条记录,一月下来这个表记录数量多大?oracle中一张表的记录数超过100w后查询性能就很差了,如何保证系统性能?再比如,中国移动有上亿的用户量,表如何设计?把所有用于存在于一个表么?所以,大数量的系统,必须考虑表拆分-(表名字不一样,但是结构完全一样),通用的几种方式:(视情况而定)1)按业务分,比如手机号的表,我们可以考虑130开头的作为一个表,131开头的另外一张表以此类推2)利用oracle的表拆分机制做分表3)如果是交易系统,我们可以考虑按时间轴拆分,当日数据一个表,历史数据弄到其它表。这里历史数据的报表和查询不会影响当日交易。当然,表拆分后我们的应用得做相应的适配。单纯的or-mapping也许就得改动了。比如部分业务得通过存储过程等此外,我们还得考虑缓存这里的缓存,指的不仅仅是hibernate,hibernate本身提供了一级二级缓存。这里的缓存独立于应用,依然是内存的读取,假如我们能减少数据库频繁的访问,那对系统肯定大大有利的。比如一个电子商务系统的商品搜索,如果某个关键字的商品经常被搜,那就可以考虑这部分商品列表存放到缓存(内存中去),这样不用每次访问数据库,性能大大增加。简单的缓存大家可以理解为自己做一个hashmap,把常访问的数据做一个key,value是第一次从数据库搜索出来的值,下次访问就可以从map里读取,而不读数据库;专业些的目前有独立的缓存框架比如memcached等,可独立部署成一个缓存服务器。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。