Archive | concurrency RSS feed for this section

Java 并发之内存模型整理

一、概述

Java线程之间的通信由Java内存模型JMM控制,[highlight]JMM决定一个线程对共享变量的写入何时对另一个线程可见[/highlight]。从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。Java内存模型的抽象示意图如下:

jmm2

从上图来看,线程A与线程B之间如要通信的话,必须要经历下面2个步骤:

  1. 首先,线程A把本地内存A中更新过的共享变量刷新到主内存中去。
  2. 然后,线程B到主内存中去读取线程A之前已更新过的共享变量。

在线程运行的时候有一个内存专用的一小块内存,当[......]

阅读全文

Tags: , , ,

Comments { 0 }

Java 并发之 Fork/Join

一、概述

Fork/join是java提供的并行执行的框架。其核心是:把一个大人物分割成若干小人物,再把小任务执行结果合并到大任务 。具体说:Fork把大任务切分成若干小任务并行执行,join把小任务的执行结果进行合并,得到大任务的结果。

通过使用 Doug Lea 提供的 Fork/Join 框架,软件开发人员只需要关注任务的划分和中间结果的组合就能充分利用并行平台的优良性能。其他和并行相关的诸多难于处理的问题,例如负载平衡、同步等,都可以由框架采用统一的方式解决。这样,我们就能够轻松地获得并行的好处而避免了并行编程的困难且容易出错的缺点。

二、适用范围

如果一个应用能被分解成多个子任务,并且组合多个子任务的结果就能够获得最终的答案,那么这个应用就适合用 Fork/Join 模式来解决。
folk_join

三、示例

以计算Fibonacci为例,Fibonacci 的返回值为 Inte[......]

阅读全文

Tags:

Comments { 1 }

并发之synchronize归纳

关于synchronized关键字,不多解释,简单归纳备注下。

  • 锁的对象:对于实例同步方法,锁是当前实例对象。对于静态同步方法,锁是当前对象的Class对象。对于同步方法块,锁是Synchonized括号里配置的对象。
  • ?使用synchronized关键字,有两种语法结构:同步代码块和同步方法。
  • synchronized关键字并不是方法签名的一部分。所以当子类覆写父类中的同步方法或是接口中声明的同步方法的时候,synchronized修饰符是不会被自动继承的。
  • 构造方法不可能是真正同步的(尽管可以在构造方法中使用同步块)。
  • 同步代码块被认为比同步方法更加的基础。如下两种声明方式是等同的:

  • 同步实例方法在其子类和父类中使用同样的锁。
  • 内部类方法的同步却独立于其外部类,[......]

阅读全文

Comments { 0 }

java 并发相关理论整理

在整理java并发相关内容的时候发现,很多都要有些前提或者术语,尽管整理这些是以基于工程或者实践的角度。但是这些更像定义、定理的东西也是理解了,后面基于其的实现和应用的理解才足够完整和有依据。

一、?线程安全

当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替运行,并且不需要额外的同步及在调用方代码不必做其他的协调,这个类的行为仍然是正确的,那么这个类就是线程安全的。

显然只有资源竞争时才会导致线程不安全,因此无状态对象永远是线程安全的

二、Happens-before法则

Java存储模型有一个happens-before原则,就是如果动作B要看到动作A的执行结果(无论A/B是否在同一个线程里面执行),那么A/B就需要满足happens-before关系。

happens-before完整规则:

  • 同一个线程中的每个Acti[......]

阅读全文

Tags: , ,

Comments { 0 }

java并发之volatile总结

一 、一句话总结:?

volatile 使得被其修饰的字段,在内存模型中被所有线程看到的值都是一致的。即一个volatile的变量被一个线程修改后马上就会对其他线程可见。

二、语义解释

volatile包含以下语义:

(1)Java 存储模型不会对valatile指令的操作进行重排序:这个保证对volatile变量的操作时按照指令的出现顺序执行的。

(2)volatile变量不会被缓存在寄存器中(只有拥有线程可见)或者其他对CPU不可见的地方,每次总是从主存中读取volatile变量的结果。也就是说对于volatile变量的修改,其它线程总是可见的,并且不是使用自己线程栈内部的变量。也就是在happens-before法则中,对一个valatile变量的写操作后,其后的任何读操作理解可见此写操作的结果。

三、使用条件

您只能在有限的一些情形下使用 volatile 变[......]

阅读全文

Tags: , ,

Comments { 0 }