共享(shared)(多个线程访问)和可变(mutable)状态
synchronized提供同步机制
synchronized同步:独占的加锁机制
volatile同步:
显示锁同步:explicit lock
原子变量同步
非线程安全的操作:
非原子操作[cpu有哪些原子操作]
结果状态依赖前一个状态
程序原子方式的操作:
程序原子方式:代码不一定需要全部执行完毕,须保证其它程序不同时进入同一段代码(同一个环境)或者使用同一个竞争的变量(如:ActomicLong)
程序一般通过加锁来确保程序原子性操作
JAVA提供内置锁来提供原子性,synchronized(提供同步代码块),每个java对象都可以用作一个实现同步的锁,这些锁被称为内置锁或监视锁
JAVA的内置锁是一种互斥锁
锁的重入: 当一个线程尝试获取已经由自己获取的锁时,是会成功的
如子类覆盖父类的synchronized,调用super方法
同步和锁的区别:锁实现了互斥,同步=互斥+内存可见性
同步还有一个重要的是内存可见性:
我们不仅希望可以互斥操作,而且希望确保一个线程修改了对象状态之后,其它线程可以看到发生的变化
(synchronized代表同步)
一种常见的加锁约定:
将所有的可变状态都封装在对象内部,并通过对象的内置锁对所有访问可变状态的代码路径进行同步,使该对象上不会发生并发访问。
许多线程安全的类都使用了这种方式,如Vector和其他的同步集合类
活跃性和性能
应该尽量将不影响共享状态且执行时间较长的操作从同步代码块中分离出去 以及不要使用阻塞的操作和注意循环内的操作
但获取锁和释放锁需要消耗资源和时间,不应把代码分的太细
<!-------------------------------------------------------------------------------------------------------!>
3.1 可见性
如:线程有自己的私有内存,线程将变量写到内存中,其它线程还是从自己线程内存中读取
即写线程的操作对读线程不可见 + p28(42)(重排序)
只要数据在多个线程之间共享,就需要正确的同步
3.1.2 非原子的64位操作 p29(43)
java内存模型要求:变量的读操作和写操作都必须是原子性的,(变量:任何变量?ps:查看java内存模型)
对于非volatile类型的long和double变量,JVM允许将64位的读操作或写操作分解为2个32位的操作
3.1.3 加锁和可见性
为什么在访问某个共享可变变量时,需要所有线程在同一个锁上 => 这样保证 同步代码块的变量是 可见性的
这种锁:称之为同步锁 ?
(即锁释放的时候,线程会把线程中的值写入到内存中 ?)
3.1.4 volatile变量
volatile变量不会和其它内存操作进行重排序,volatile不会被缓存在寄存器或其它处理器不可见的地方。
访问volatile变量时不会执行加锁操作,不建议过度以来volatile,因为会使代码更加脆弱
仅当volatile变量可以简化代码实现以及同步策略的验证时,才应该使用它们。p31(45)
3.2 发布和逸出
发布: 使对象能够在当前作用域之外的代码中使用。
逸出: 当某个不该发布的对象被发布时(如对象构造完成之前发布对象),这种情况成为逸出
(fixme:逸出问题其实是另一种控制作用域的方法)
p33(47)这可能是sla对字段等精确作用域控制的原因
3.2.1 隐式的(构造函数中)使this引用逸出,如:构造器中创建并发布内部类,构造器中启动一个线程
3.3 线程封闭
fixme:类似ThreadLocal,局部变量
没有共享数据,每个线程使用自己的数据
3.3.1 Ad-hoc线程封闭(比较脆弱,不推荐使用)
:维护线程封闭性的职责完全由程序(这里程序指语言特性)来实现。
在volatile变量上有一种特殊的线程封闭,保持一个线程写,多个线程读,则写线程可以进行读取-修改-写入
(即把变量封闭到了写线程,fixme:这里的volatile变量如果是引用也可以??应该不可以)
3.3.2 栈封闭:线程内部自己的局部变量
3.3.3 ThreadLocal类: currentThread => ThreadDataMap,
当某个频繁执行的操作需要一个临时对象,例如一个缓冲区,而同时又希望避免每次执行时重新分配该临时对象,即可以使用ThreadLocal
ThreadLocal变量类似全局变量,降低了代码的重用性,并在类之间引入了隐含的耦合性
3.4 不变性 immutable object
不可变对象一定是线程安全的:
当满足以下条件时,对象才是不可变的:=> sla的不可变对象
1. 对象创建以后状态就不能修改
2. 对象的所有域都是final的
3. 对象是正确创建的(对象创建期间,this引用没有逸出)
3.4.1 final
3.4.2 volatile
3.1.3 加锁和可见性
3.1.4 volatile 变量 比 synchronized 更轻量级
(中文翻译的根本看不懂,以下是自己翻译和理解)
When thread A writes to a volatile variable and subsequently thread B reads that same variable, the values of all variables that were visible to A prior to writing to the volatile variable become visible to B after reading the volatile variable. So from a memory visibility perspective, writing a volatile variable is like exiting a synchronized block and reading a volatile variable is like entering a synchronized block.
-- ps: cpu 的读和写是原子操作的
thread A对volatile 变量进行写入,随后thread B读取此变量的值,在A写入之前,所有值对A是可见的(即A直接访问的是(进程的)内存,不是自己线程的内存区域),在B读入之后,对B是可见的。所以什 么是内存可见性,写入一个volatile变量 类似 退出一个synchronized block,读入一个 volatile变量 类似 进入一个synchronized block .
退出一个synchronized block,即还没有释放锁,其它线程 读写不了,
进入一个synchronized block,即还没有获得所,线程读不了
总结:volatile 原理是使用了CPU读 写的原子性,并强制线程从进程内存中读取,而不是线程自己的内存。
引用: http://www.iteye.com/magazines/131
- 对引用变量和大部分基本类型变量(除long和double之外)的读写是原子的。
- 对所有声明为volatile的变量(包括long和double变量)的读写是原子的。
java.util.concurrent包中的一些类提供了一些不依赖同步机制的原子方法
相关推荐
Java并发编程实践是Java开发中不可或缺的一个领域,它涉及到如何高效、正确地处理多线程环境中的任务。这本书的读书笔记涵盖了多个关键知识点,旨在帮助读者深入理解Java并发编程的核心概念。 1. **线程和进程的...
### Java并发编程实践笔记知识点详解 #### 一、保证线程安全的方法 1. **不要跨线程访问共享变量:** 当多个线程共享某个变量时,若其中一个线程修改了该变量,其他线程若没有正确同步,则可能读取到错误的数据。...
Java并发编程实践笔记 Java并发编程实践笔记是一份关于Java并发编程的实践笔记,涵盖了多种关于线程安全、并发编程的实践经验和原则。下面是从笔记中总结的知识点: 1. 保证线程安全的三种方法:不要跨线程访问...
在Java并发编程中,数据的封装与访问控制、线程安全性的考量、同步...以上知识点是从提供的文件内容中提取出的,旨在帮助理解Java并发编程的基础概念和技术实践。掌握这些概念对于开发高效且可靠的并发程序至关重要。
这本"Java并发编程学习笔记"可能是作者在深入研究Java并发特性、工具和最佳实践过程中积累的心得体会。下面,我们将根据这个主题,探讨一些关键的Java并发编程知识点。 1. **线程与进程**:在多任务环境中,线程是...
### Java并发编程知识点详解 #### 一、线程状态与管理 在Java中,线程具有多种状态,这些状态的变化反映了线程在其生命周期中的不同阶段。理解这些状态及其转换对于编写高效、健壮的并发程序至关重要。 - **NEW**...
JAVA并发编程实践-构建执行程序块-学习笔记 JAVA并发编程实践是指在JAVA编程语言中,使用多线程、并发编程来实现高效、可靠的程序执行。构建执行程序块是指在并发编程中,使用线程安全的类来管理状态,以确保程序的...
《Java并发编程实践》这本书是Java开发者深入理解并发编程的重要参考。以下是对书中关键知识点的总结: 1. **线程和进程的区别** - **线程**:是程序执行的最小单位,一个进程中可以有多个线程,它们共享同一块...
总的来说,Java并发编程实践中的任务执行是一个涉及线程调度、线程池管理、任务生命周期控制、结果处理等多个方面的复杂主题。理解和掌握这些概念和技术,能够帮助开发者编写出更加高效、可靠的并发程序。
Java并发编程实践中的线程池是一个关键的概念,它在多线程编程中扮演着至关重要的角色,有效地管理和调度线程资源,以提高系统的性能和效率。线程池通过复用已存在的线程来减少线程的创建和销毁开销,避免了频繁的上...
在Java并发编程中,线程安全是一个至关重要的概念,它涉及到多线程环境下对共享数据的正确管理和访问。线程安全意味着当多个线程同时访问一个对象或数据时,对象的状态能够保持一致性和完整性,不会因为并发导致数据...
Java是最先支持多线程的开发的语言之一,Java从一开始就支持了多线程能力,因此Java开发者能常遇到上面描述的...这也是我想为Java并发技术而写这篇系列的原因。作为对自己的笔记,和对其他Java开发的追随者都可获益的。
在Java并发编程中,线程的关闭和取消是一项重要的任务,因为不正确的处理可能导致数据不一致、资源泄漏等问题。在Java中,强制停止线程并不是一个推荐的做法,因为这可能会导致系统状态的不稳定。传统的`Thread.stop...
使用java.util.concurrent类库构造安全的并发应用程序的基础。共享其实就是某一线程的数据改变对其它线程可见,否则就会出现脏数据。
1. **Java并发基础**:首先,笔记可能会介绍Java并发的基础概念,包括线程的创建(通过`Thread`类或实现`Runnable`接口)、线程的状态(新建、运行、阻塞、等待、死亡)以及线程的生命周期。 2. **同步机制**:Java...
《Java并发编程实战》是一本深入探讨Java多线程和并发编程的经典著作,它为开发者提供了全面、实用的指导,帮助他们理解和解决并发问题。这本书的中文版使得更多的中国开发者能够受益于其丰富的知识和实践经验。 ...
《实战Java高并发程序设计》是一本专注于Java并发编程实践的书籍,试读版提供了前两章的内容,为读者提供了一个初步了解并发编程基础的窗口。在Java领域,并发编程是构建高性能、高效率系统的关键技术,对于软件开发...
"java高并发.txt"可能是一份文档或笔记,涵盖了Java并发编程的核心概念和技术。它可能详细解释了线程的生命周期、线程安全问题(如数据竞争、活锁、死锁)、并发工具类(如CountDownLatch、CyclicBarrier、Semaphore...
首先,"Java并发编程笔记"这部分内容可能涵盖了以下几个关键知识点: 1. **线程基础**:线程的创建、启动、中断和销毁,以及如何使用`Thread`类和`Runnable`接口来创建线程。 2. **并发控制**:包括`synchronized`...