线程安全和不可变性(Thread Safety and Immutability)

2023-12-03 04:08

本文主要是介绍线程安全和不可变性(Thread Safety and Immutability),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文链接:http://tutorials.jenkov.com/java-concurrency/thread-safety-and-immutability.html

竞争条件只会在多个线程访问相同的资源并且一个或多个线程改写这个资源的情况下发生。如果多个线程只是同时读取相同的资源不会导致竞争条件的发生。

我们可以通过某种手段让共享的对象不可改变,从而可以确保这些不可改变的共享对象不会被任何一个线程改变,因此这些不可改变的对象是线程安全的。下面是一个例子:

    public class ImmutableValue {private int value = 0;public Immutablevalue(int value) {this.value = value;}public int getValue() {return this.value;}}

注意,ImmutableValue 类的实例的值是通过构造方法传递的、 ImmutableValue 类是没有 set 方法的,一旦 ImmutableValue 类的实例被创建以后就不能改变它的值。 ImmutableValue 类的实例是不可改变的,可以通过 getValue() 方法来读取它的值。

如果需要在这个 ImmutableValue 类的实例上执行操作,可以把不可变对象原有的值结合需要的操作产生一个新的值,然后用这个新的值新建一个实例,最后把这个新建的实例返回。下面是一个 add 操作的例子:

    public class ImmutableValue {private int value = 0;public ImmutableValue(int value) {this.value = value; }public int getValue() {return this.value;}public ImmutableValue add(int valueToAdd) {return new ImmutableValue(this.value + valueToAdd);}}

注意, add() 方法用 add 操作的结果重新构造了一个 ImmutableValue 类的实例并返回,而不是直接对原来的不可变对象的值 value 做 add 操作。

引用不是线程安全的!

记住,即使一个对象是不可变的因此这个对象是线程安全的,但这个对象的引用未必是线程安全的。看下面的例子:

    public class Calculator {private ImmutableValue currentValue = null;public ImmutableValue getValue() {return currentValue;}public void setValue(ImmutableValue newValue) {this.currentValue = newValue;}public void add(int newValue) {this.currentValue = this.currentValue.add(newValue);}}

Calculator 类持有 ImmutableValue 类的实例的一个引用。注意,可以通过 setValue() 和 add() 方法来改变这个引用指向的对象。因此,即使 Calculator 类在内部使用了一个不可变的对象,但并不是说这个 Calculator 类就不可改变,它还是线程不安全的。换句话说, ImmutableValue 类是线程安全的,但使用了这个类的类未必也是线程安全的。这是通过不可变性来达到线程安全时需要注意的问题。

为了使 Calculator 类达到线程安全,可以在 getValue()、 setValue() 和 add() 方法前声明为 synchronized 方法。声明为 synchronized 方法消除了这个问题。

Next: Java 内存模型

这篇关于线程安全和不可变性(Thread Safety and Immutability)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/448010

相关文章

客户案例:安全海外中继助力知名家电企业化解海外通邮困境

1、客户背景 广东格兰仕集团有限公司(以下简称“格兰仕”),成立于1978年,是中国家电行业的领军企业之一。作为全球最大的微波炉生产基地,格兰仕拥有多项国际领先的家电制造技术,连续多年位列中国家电出口前列。格兰仕不仅注重业务的全球拓展,更重视业务流程的高效与顺畅,以确保在国际舞台上的竞争力。 2、需求痛点 随着格兰仕全球化战略的深入实施,其海外业务快速增长,电子邮件成为了关键的沟通工具。

安全管理体系化的智慧油站开源了。

AI视频监控平台简介 AI视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。用户只需在界面上进行简单的操作,就可以实现全视频的接入及布控。摄像头管理模块用于多种终端设备、智能设备的接入及管理。平台支持包括摄像头等终端感知设备接入,为整个平台提

2024网安周今日开幕,亚信安全亮相30城

2024年国家网络安全宣传周今天在广州拉开帷幕。今年网安周继续以“网络安全为人民,网络安全靠人民”为主题。2024年国家网络安全宣传周涵盖了1场开幕式、1场高峰论坛、5个重要活动、15场分论坛/座谈会/闭门会、6个主题日活动和网络安全“六进”活动。亚信安全出席2024年国家网络安全宣传周开幕式和主论坛,并将通过线下宣讲、创意科普、成果展示等多种形式,让广大民众看得懂、记得住安全知识,同时还

Thread如何划分为Warp?

1 .Thread如何划分为Warp? https://jielahou.com/code/cuda/thread-to-warp.html  Thread Index和Thread ID之间有什么关系呢?(线程架构参考这里:CUDA C++ Programming Guide (nvidia.com)open in new window) 1维的Thread Index,其Thread

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟

线程的四种操作

所属专栏:Java学习        1. 线程的开启 start和run的区别: run:描述了线程要执行的任务,也可以称为线程的入口 start:调用系统函数,真正的在系统内核中创建线程(创建PCB,加入到链表中),此处的start会根据不同的系统,分别调用不同的api,创建好之后的线程,再单独去执行run(所以说,start的本质是调用系统api,系统的api

java线程深度解析(六)——线程池技术

http://blog.csdn.net/Daybreak1209/article/details/51382604 一种最为简单的线程创建和回收的方法: [html]  view plain copy new Thread(new Runnable(){                @Override               public voi

java线程深度解析(五)——并发模型(生产者-消费者)

http://blog.csdn.net/Daybreak1209/article/details/51378055 三、生产者-消费者模式     在经典的多线程模式中,生产者-消费者为多线程间协作提供了良好的解决方案。基本原理是两类线程,即若干个生产者和若干个消费者,生产者负责提交用户请求任务(到内存缓冲区),消费者线程负责处理任务(从内存缓冲区中取任务进行处理),两类线程之

java线程深度解析(四)——并发模型(Master-Worker)

http://blog.csdn.net/daybreak1209/article/details/51372929 二、Master-worker ——分而治之      Master-worker常用的并行模式之一,核心思想是由两个进程协作工作,master负责接收和分配任务,worker负责处理任务,并把处理结果返回给Master进程,由Master进行汇总,返回给客

java线程深度解析(二)——线程互斥技术与线程间通信

http://blog.csdn.net/daybreak1209/article/details/51307679      在java多线程——线程同步问题中,对于多线程下程序启动时出现的线程安全问题的背景和初步解决方案已经有了详细的介绍。本文将再度深入解析对线程代码块和方法的同步控制和多线程间通信的实例。 一、再现多线程下安全问题 先看开启两条线程,分别按序打印字符串的