多线程单例模式杂谈

多线程单例模式杂谈

单例模式

单例模式,请见设计模式,大概来说就是我们确保一个类只有一个实例,而且自行实例化给整个系统提供这个实例的使用权(Bean工厂注入等)。又有懒汉式,饿汉式之分。

一个对象资源

多线程操作一个对象存在线程安全问题:如何理解?关键是业务

如何理解

一个对象,在系统中我们只有一个对象存在,而我们有很多的线程去访问他,同时对这个对象进行操作(如读取,变更其中某个变量等),那么这样便会存在问题。

首先我们要知道为什么需要多线程操作

一个资源,现在有多个程序需要对这个资源进行操作,如播放视频,我们不可能先读取画面,等画面放完我们再去读取音频,同样,我们的计算机也不可能一次只运行一个程序,他是多个程序同时运行的。

首先我们需要了解多线程操作的原理:有多个线程去争抢一个对象资源的使用权,CPU负责给这些线程进行分配运行资源(时间片理论),线程A争取到了时间片,在这个时间段内执行A线程,然后时间片时间到了之后A退出或者sleep,B抢到时间片,B进入CPU被运行,然后再换成A抢到时间片进行运行,这在一秒内进行十分多的次资源分配可能其只运行0.001m就退出了。正是这种资源快速分配才能做到我们看视频的时候既能看到画面也能读取到音频,以及我们同时运行多个程序,在后台等。

两个问题

这样产生了两个问题:①资源分配的顺序②资源分配的位置

①资源分配的顺序

​ 虽然我们是设置了A与B等线程去争抢CPU的资源,这样实现了同时运行了多个程序的可能,但是其随机分配还是存在问题,这样并不能保证资源分配的公平性,比如B线程分配时间片运行结束了之后其退出,然后再次争抢资源的时候他又抢到了时间片,并且一直抢得到,这样就不合适,要是一直这样他岂不是一直只能运行这一个程序,所以我们需要设置一种规则,将他排除出去,我们一般通过线程池创建线程,对线程进行管理,同时我们设立阻塞队列,将需要使用线程的请求或者程序放在队列中,线程随机取得其中的资源进行操作。

②资源分配的位置

​ 其次就是资源分配的“位置”问题,首先我们来明确一下这个“位置”问题是什么?
​ 我们来做一个假设,A线程与B线程一起争抢同一个对象C,A先抢到时间片,然后对对象进行了对应的操作,C对象被A操作的部分变更了,他退出后本来应该在下次进入的时候继续进行自己未完成的操作,但是这个时候B线程进入并且同时CPU分配给B资源后B也对相同的位置进行了更改,这样等待A回来的时候其便运行错误,这就是所谓的“位置“。为了防止这种情况,我们便会对A已经操作过的资源加锁,这样B就不能对A的数据进行操作,这样便实现了线程安全。但是这样可分配给其他线程的资源的量便减少了,所以我们需要根据业务情况来设置是否加锁,以及加什么样的锁。

问题·解决

​ 产生这个问题的原因就是当时在service的实现类里面使用了StringBuffer类来拼接字符串,而StringBuffer是线程不安全的,这时候就去想serverlet到底存不存在线程安全问题。例如服务器收到了多个请求,其请求的是同一个接口,这样的话会不会有问题。

​ 因为serverlet是单例模式,所以其只存在一个实例对象,然后多个请求是多线程,但是其并不像计算机内的程序一样,这个请求执行一下还没搞完,又去执行另一个请求。它类似于一个容器,多线程都在阻塞队列中,他们争抢进入这个容器的入口,一旦进入不执行完请求不会接受新的请求进入,这其实就是相当于这个请求进去之后把容器从里面反锁了,在里面把事情办完之后才出来让下一个请求进去,这就是根据我们的业务需要对这个容器上了锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值