Java并发0.1

一、Java概念
1.什么是并发
所谓并发,计算机同时执行多个程序。
一开始计算机是单核cpu,当时主要升级的是cpu的时钟频率。到后来时钟频率提升缓慢,,这时就采用了多核的模式。多个处理器来使用。这样计算机的性能一下子就有很明显的提升。那时候一般的程序都是使用单线程的。无法有效的使用多核的强大之处。于是就采用了并发,多线程的方式。
2.并发的优势
使用并发的优势发挥多处理器的强大能力,使得构建简单,异步处理的简易化,
1.多处理器的强大能力:主要原因在于同时处理多件事情,不会在资源过度的停滞,大大提高了资源的使用率。
2.构建简单:如果是单线程的话,每一个程序里就都需要完成所有事情,需要考虑的因素很多,每一处的变化所影响的也会变得很多。而使用并发,就能将其拆分。将很多复杂的事情变得简单。
3.异步处理的简易化:在过去由于线程数量少,那必然每个程序在面对阻塞时,会影响到整个程序的执行。这时就需要采取非阻塞I/O来处理,非阻塞I/O的操作难度比较大。而线程多了。就可以采用阻塞I/O操作难度一下就降下来了。
3.并发存在的问题
使用并发时,当编程不规范,或者一些细节没有考虑到,就引发出问题。这时就需要我们去解决。主要的问题为三类。
1.安全性问题:所谓安全性问题,核心问题对于数据使用问题。
数据使用问题可以看作对数据的同步,或者一致性的思考
所谓数据同步问题,当第一个线程修改了数据,第二个线程无法读到最新数据时就会存在问题。如果这个数据准确性要求很高那么问题就很大。如统计每一次调用的次数。这样就很可能导致统计数量比实际数量少很多。又或者不应该修改这个数据的地方,修改了这个数据。
数据一致性,其核心为原子问题,就不得不说一个名词竞态条件,竞态条件的意义就是当你要执行一行命令前判断这个命令是否需要执行。有判断条件则就是竞态条件。这时需要判断是否需要将整个复合操作作为一个原子操作。不需要就无需原子化,但如果需要没做原子化,就会造成原子问题。
两者不存在划分,是共同可能存在的,当对一个数据用在判断时,那必要是需要同步才能精准的知道是否需要执行。而一致性则表明在判断过程中不会有其他的线程来进行操作。在同一块代码块中两者就需要同时考虑。
用一句话来形式,所谓安全,多线程同时访问某个类时,能够正确的做出相应的事情。
哪些一定是安全的呢,1.无状态的类。2.不可变的。
无状态类,指的就是你的操作不与其他任何数据有关系。指和自己本身有关系。不存在对于共享数据的判断。
不可变的,就相当于你输入一个数,在任何情况下返回的都是一样的。
2.活跃性问题
一句话来描述活跃性问题。所谓活跃性,就是这个类能够最终执行下去。执行不下去那必然就是存在活跃性问题。
活跃性主要的问题有:死锁…
3.性能问题
二、如何解决问题
1.安全性问题的解决思路
在解决安全性问题,很大程度上是对数据共享上进行思考,想象共享时会发生什么问题。
比如在不应该修改数据的地方修改了、在获取最新数据时获取到是已经失效的数据、以及在判断执行时重复执行等等,我们能做的就是尽可能的避免这些问题的出现。
判断执行时重复执行
在对于判断执行时重复执行这个问题上,唯一可以做的就是将复合操作调整为原子操作。在那一刻只有一个线程能够操作它。而这样唯一的办法就是使用锁机制,当加锁后,线程就无法多线程执行同一把锁的代码,这样就能保住数据的一致性。
锁的特点,同时只有一个线程进入该代码块,一个线程在多次访问同一把锁时,如果已有这一把锁无需再次获取。如果该代码块需要进行很长时间的处理,那不建议使用锁,很造成长时间的堵塞,影响性能。
对于数据的访问所存在的问题
解决数据访问问题最好的方法那就是不共享,只要不共享,就不会存在同步问题,及在任何时候访问下都是访问的最正确的数据。
不共享的所使用的技术叫线程封闭。
1.Ad-hoc线程封闭
2.栈封闭
3.ThreadLocal类
如果数据需要共享,那么必须关注两个点,一、共享的范围,二、数据同步
一、共享范围,
指的是除了本身以外还有谁能够访问。让谁访问这个操作叫做发布。这时可能存在一个问题,当你没有发布给一个类,但是这个类有访问的可能这叫逸出。
存在逸出是一个很不安全的事情,因为无法预料什么时候,什么地方修改了数据,又或者说不应该修改的地方被修改了。
有两个种方式避免:
1.使用finial,使用这个能够有效的保护数据,它的作用就是当创建好一次之后就无法修改,无法修改那数据当然就不会存在同步问题了。在源头解决问题。finial对于对象来说,只是无法重新创建,但依然可以修改对象中的属性。所以在对象中的属性也需要适当使用finial来修饰。
2.当一个方法返回对象时,不要直接返回,而是返回克隆对象。这样即便修改了,也不会对原本对象有什么影响。
二、数据同步
同步的含义是当数据修改后能让别的线程感知到这个数据已经修改过了。访问时会访问最新的数据。
volatile的主要作用是将程序不会自动编排,固定执行顺序,不会将数据放入程序感知不到的缓存中。
而使用了finial,因为是不变的所有自然而然的就不需同步了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值