java并发编程实战笔记-线程安全性

什么是线程安全性

线程安全性定义中最核心的概念就是:**正确性**。我们将单线程的正确性近似
定义为“所见即所知”,当多个线程访问这个类的时候,始终能表现出正确的行为,
那么这个类就是线程安全类。
当多个线程访问某个类时,不管运行时环境采用什么调度方式或者这些线程将如何
交替运行,并且调用代码时,不需要额外的同步,就可以产生正确的结果。这个类
就是线程安全类。
在线程安全类上执行任何串行或者并行的操作都不会使对象处于无效状态。
可重入代码:就是这段代码,和其他代码不存在共享状态,只包含形参和局部变量,
肯定是线程安全的,又被称为无状态。

竞态条件

当计算的正确性取决于多个线程执行的顺序时,就会发生竞态条件。常见的竞态条
件就是先检查后执行操作。延迟加载中,getInstance中先判断是否为空,然后在
创建实例返回。
还有另一种常见的:读取-修改-写回竞态条件。
复合操作。只要不是原子操作,就会有问题。可通过加锁变成原子操作。
只要有竞态条件,就不是线程安全的。

用锁保护状态

如果要使用同步来协调对一个变量的访问,那么在访问这个变量的所有位置上都要
使用同步。并且使用锁来协调的时候,还必须使用同一个锁。
每个可变的或者共享的变量都应该要有一个锁来保护。
只有多线程共享的,可变的数据才需要锁来保护。
对于包含多个变量的不变性条件,其中涉及的所有变量都需要使用同一个锁来保护。
synchronized只能确保单个方法是线程安全的,对于多个操作的符合操作,还需要
另外的同步才可以。
注意:并不是只有修改的时候,才需要同步。
当执行较长时间的运算时,或者无法快速完成的操作,一定不要持有锁。
时间: 2024-12-07 22:14:41

java并发编程实战笔记-线程安全性的相关文章

【java并发编程实战】-----线程基本概念

学习Java并发已经有一个多月了,感觉有些东西学习一会儿了就会忘记,做了一些笔记但是不系统,对于Java并发这么大的"系统",需要自己好好总结.整理才能征服它.希望同仁们一起来学习Java并发编程,共同进步,互相指导. 在学习Java并发之前我们需要先理解一些基本的概念:共享.可变.线程安全性.线程同步.原子性.可见性.有序性. 共享和可变 要编写线程安全的代码,其核心在于对共享的和可变的状态进行访问. "共享"就意味着变量可以被多个线程同时访问.我们知道系统中的资

java并发编程实战笔记

1.复合操作 若一个类里有多个属性状态,对每个属性使用atomic类修饰,并且一个属性更新,要在同一原子操作内更新其他所有属性,这样才是线程安全类.需要整体类的状态操作是原子的. 要保持状态的一致性,就需要在单个原子操作中更新所有相关的状态变量. 判断同步代码块的合理大小,要权衡安全性.简单性和性能. 当执行时间较长的计算或可能无法快速完成的操作(如网络IO.控制台IO)一定不要持有锁. 2.对象的共享 1)可见性 为了确保所有线程都能看到共享变量的最新值,所有执行读操作或写操作的线程都必须在同

JAVA并发编程学习笔记------线程的三种创建方式

创建线程一般有如下几个方式: 1. 通过继承Thread类来创建一个线程: /** * 步骤1:定义一个继承Thread类的子类 * 步骤2:构造子类的一个对象 * 步骤3:启动线程: * */ public class ThreadTest{ public static void main(String[] args) { //构造子类对象 SubThread subThread = new SubThread(); //启动线程 subThread.start(); } } //定义继承Th

读书笔记-----Java并发编程实战(一)线程安全性

线程安全类:在线程安全类中封装了必要的同步机制,客户端无须进一步采取同步措施 示例:一个无状态的Servlet 1 @ThreadSafe 2 public class StatelessFactorizer implements Servlet{ 3 public void service(ServletRequest req,ServletResponse resp){ 4 BigInteger i = extractFromRequest(req); 5 BigInteger[] fact

《Java并发编程实战》第二章 线程安全性 读书笔记

一.什么是线程安全性 编写线程安全的代码 核心在于要对状态访问操作进行管理. 共享,可变的状态的访问 - 前者表示多个线程访问, 后者声明周期内发生改变. 线程安全性 核心概念是正确性.某个类的行为与其规范完全一致. 多个线程同时操作共享的变量,造成线程安全性问题. * 编写线程安全性代码的三种方法: 不在线程之间共享该状态变量 将状态变量修改为不可变的变量 在访问状态变量时使用同步 Java同步机制工具: synchronized volatile类型变量 显示锁(Explicit Lock

《Java并发编程实战》第八章 线程池的使用 读书笔记

一.在任务与执行策略之间的隐性解耦 有些类型的任务需要明确地指定执行策略,包括: . 依赖性任务.依赖关系对执行策略造成约束,需要注意活跃性问题.要求线程池足够大,确保任务都能放入. . 使用线程封闭机制的任务.需要串行执行. . 对响应时间敏感的任务. . 使用ThreadLocal的任务. 1. 线程饥饿死锁 线程池中如果所有正在执行任务的线程都由于等待其他仍处于工作队列中的任务而阻塞,这种现象称为线程饥饿死锁. 2. 运行时间较长的任务 Java提供了限时版本与无限时版本.例如Thread

Java并发编程学习笔记(一)线程安全性 1

什么是线程安全性: 要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享的和可变的状态的访问."共享"意味着变量可以由多个线程同时访问,而"可变"则意味着变量的值在其生命周期内可以发生变化. 一个对象是否需要线程安全的,取决于他是否被多个线程访问.这指的是在程序中访问对象的方式,而不是对象要实现的功能.要使得对象时线程安全的,需要采用同步机制来协同对对象可变状态的访问.如果无法实现协同,那么可能导致数据破坏以及其他不该出现的结果. 如果当多个线程访

《Java并发编程实战》第十六章 Java内存模型 读书笔记

Java内存模型是保障多线程安全的根基,这里仅仅是认识型的理解总结并未深入研究. 一.什么是内存模型,为什么需要它 Java内存模型(Java Memory Model)并发相关的安全发布,同步策略的规范.一致性等都来自于JMM. 1 平台的内存模型 在架构定义的内存模型中将告诉应用程序可以从内存系统中获得怎样的保证,此外还定义了一些特殊的指令(称为内存栅栏或栅栏),当需要共享数据时,这些指令就能实现额外的存储协调保证. JVM通过在适当的位置上插入内存栅栏来屏蔽在JVM与底层平台内存模型之间的

JAVA并发编程实战 读书笔记(二)对象的共享

<java并发编程实战>读书摘要 birdhack 2015年1月2日 对象的共享 JAVA并发编程实战读书笔记 我们已经知道了同步代码块和同步方法可以确保以原子的方式执行操作,但一种常见的误解是,认为关键之synchronized只能用于实现原子性或者确定临界区.同步还有另一个重要的方面:内存可见性. 1.可见性 为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制. 在没有同步的情况下,编译器.处理器以及运行时等都可能对操作的执行顺序进行一些意想不到的调整.在缺乏足够同步的多线程程