现在soa 与分布式计算已经成为互联网公司技术的标配
那他包含的知识点应该熟悉了解,并以此为基础,去应用,调优各种soa的框架。
包含如下的四点,是分布式的基础。
a java 多线程 承接高吞吐量。
b java nio 承接高并发,与交互协议的定制。
c java 反射 完成序列化与反序列化。
d 设计模式的应用 保证应用的扩展性。
现在说说这java多线程
对于现在的操作系统软件与硬件,都有一个共同的目标,让程序能够并行的运算。而并行的基本单位是线程,因此我们应该了解线程。
有如下几个问题?先提出来.
- 线程并行时,其jvm里面是怎么进行内存管理的?怎么对共享变量是进行内存一致性的约束?
- 线程之间怎么进行协作?
对于第一个问题,java 里面线程的
内存模型这里面简单说一下
主要有堆内存,栈内存。
堆是各个线程进行共享的。而栈是线程独有的。因此如果线程之间如果说是要共享数据,那只能是放到堆里面。
线程读取共有堆数据之间是有相应的缓存器的,因此如果并行的话,不进行同步的话,就会产生a线程生产的数据还没有写到
主堆内存里面去就会被b线程将脏数据读出来进行计算,那也就是a线程的结果不被b线程看见,现实生活中可以想想转帐就了解了。
可以看如下图明白,程序怎么运行:
更厉害的就是这个程序的顺序,有可能被编译器,以及cpu进行重现编排了,这样做的目的就是为了速度快,效率高。但有些可以调顺序,有些是不能调的,那怎么办。不能调的告诉jvm,cpu就得了。
那java里面如何解决这个问题呢,那就是同步,同步是需要里面硬件进行支持的,但这个可以说比较的深了,了解一下就成, 因为了解到这里,你可以认为那些搞jvm的人只是想个办法写个c++的指令就能让cpu在数据计算的时候,看是到缓存器里面拿,还是到数据总线里面拿。
以上就是说jvm有这些功能,那我们程序员如果能用到这些功能?无非就是写一些标示让jvm里面去读,读到了,它就会按照你的指示去同步就好。
这里有几个java特有的关键字做同步的标识。
1 synchronized
2 volatile
对于 synchronized 这个 大家应该比较的熟悉,这玩意加到方法或者是块里面
那为什么这玩意一加上去就会有同步的效果呢。这里又牵扯到监视器,或者锁。
由于这个程序是人设计的,肯定有人的思想里面,大家发挥想象哈。
监视器 就像建了一个房子 但每次只能让一个线程去获取。这个房间通常里面放了一些数据,从线程从房子里面进去,再从房子里面出来,这个房子是防止其他线程进去的。
正在进入房子 --->
正在进入监视器。---不一定获得了锁 但执行了方法体里面前面一段代码ⓐ
完全进入房子 --->
获取监视器进行时。 (是竞争的时候?)
正在占有监视器--->
拥有监视器。
离开房间 ---->
释放监视器。
离开整个建筑 ---->
离开监视器。---- 已经释放了锁,但必须执行方法体里面后一部分代码
这里面灵活性做得好,进去的人想出来,可以通过两种途径,
1 里面有间休息室,可以休息,但必须将特权证得交出来。休息好了,再申请特权证在进来干活。
2 把事做完了,将特权证交出来。该干嘛,就干嘛去。
就如下面的图一样
对于
volatile 你可以看成是小型的
synchronized
但功能很弱哈,只是对于基本数据类型用的多,复杂内型,复杂的操作都不行,这个可以去查看一个资料,这玩意主要用来做标志位。原理就是线程每次读这个变量,写这个变量,都是在堆内存里面直接改的。所有A线程一改,B线程就能马上看到。
复杂的类,就不行了,复杂的操作也不行,比如volatile++都不行,这个可以查查资料。
加上这两个就不会让程序脏读,写,也不会让编辑器,以及cpu 随意的改变顺序了。
另外还有一个final 修饰的类属性,类对象没构造完成之前,中间状态不会让别的线程看见。这个也可以查查这方面的资料。
synchronized
,
volatile,
final
保证了,代码在cpu上执行指令顺序的规定。
以上是对于java 里面内存模型的一个大概了解,有如下几个特性是需要了解的。
- 现实业务的原子性。(模拟现实业务,得到预期结果)
- 内存可见性。(对于公共变量。前一原子性的操作结果,必须让后一操作看到)
- 一致性。(程序员编程的顺序与机器执行代码的顺序不一样,但设计保证了结果的一致性)
那如何在一堆的thread进行协调呢,下面文章牵扯到了thread各个api.,以及对于api的应用场景描述。