Java Concurrencyin Practice 并发编程实践系列 第二章 线程安全 Thread Safety 上

简介: Java Concurrencyin Practice 并发编程实践系列 第二章 线程安全 Thread Safety 上

Chapter 2: Thread Safety

第二章,主要讲的是线程安全的问题,及解决方法,现在写的是如何去理解线程安全

Perhaps surprisingly, concurrent programming isn’t so much about threads or locks, any more than civil engineering is about rivets and I-beams. Of course, building bridges that don’t fall down requires the correct use of a lot of rivets and I-beams, just as building concurrent programs require the correct use of threads and locks. But these are just mechanisms—means to an end. Writing thread-safe code is, at its core, about managing access to state, and in particular to shared, mutable state.

这句话的意思是,尽管并发编程涉及到线程和锁等概念,但它的本质并不局限于这些具体的实现细节,就像土木工程并不仅仅关乎铆钉和I型钢梁一样。

这句话的目的是提醒人们,对于并发编程来说,更重要的是理解并解决并发编程所带来的挑战和问题,而不仅仅局限于线程和锁的使用。并发编程涉及到如何设计并发安全的算法、如何管理共享资源、如何处理竞争条件等等。类似地,土木工程涉及到设计建造稳固的结构、解决土地利用问题、考虑自然环境等方面。

因此,理解并发编程应该超越具体的线程和锁的细节,而是注重在整体设计和解决问题的层面上进行思考和处理。这样才能更好地应对并发编程的挑战,并开发出高效、可靠的并发程序。

threads and locks. But these are just mechanisms—means to an end.

线程和锁等并发编程的机制只是实现并发编程的手段,它们并不是目标的终点。

并发编程的目标是解决问题、提高性能、改善用户体验等。线程和锁等机制只是为了支持实现这些目标而存在,它们是一种工具,通过合理的使用来达到预期的效果。

Writing thread-safe code is, at its core, about managing access to state, and in particular to shared, mutable state.

编写线程安全的代码,在其核心是管理对状态的访问,特别是对共享的、可变的状态的访问。

在并发环境下,多个线程可能同时访问和修改共享的状态,如果没有适当的管理,就会产生数据竞争和不一致的结果。

Informally, an object’s state is its data, stored in state variables such as instance or static fields.

An object’s state may include fields from other, dependent objects;

a HashMap’s state is partially stored in the HashMap object itself, but also in many Map.Entry objects.

An object’s state encompasses any data that can affect its externally visible behavior.

(instance fields, static fields: 实例字段/实例域/实例变量, 静态字段/静态域/静态变量

有时候直接看英文原版会比看翻译会更明白一点,虽然阅读过程会比较曲折,但尽量阅读。)

object’s state指的是它的数据,存储在状态变量中,例如实例变量或静态变量。(object’s state约等于object instance fields, static fields )

对象的状态可能包括来自其他相关对象的字段;例如,HashMap的状态部分存储在HashMap对象本身中,但也存储在许多Map.Entry对象中。object’s state包括所有可能影响其对外可见行为的数据。(其实就算翻译了,还是有点看不懂的。直接举例吧。)

public class Counter {
    private int count;
    public void increment() {
        count++;
    }
    public int getCount() {
        return count;
    }
}

在这个例子中,计数器 object’s state 就是它的count字段的值。

该对象的行为取决于该状态,当调用increment方法时,状态会发生变化。

Counter Object:

  • State Variables: count (an integer field)
  • State: The value of the count field
  • Behavior: The increment() method increases the value of count, and the getCount() method returns the current value of count.

In this examples, the state of an object refers to its internal data stored in state variables. The behavior of the object depends on its state, and various methods can modify the state to achieve different functionality. Managing shared mutable state correctly is crucial in concurrent programming to ensure thread safety and proper concurrent operations.

By shared, we mean that a variable could be accessed by multiple threads;

by mutable, we mean that its value could change during its lifetime.

We may talk about thread safety as if it were about code, but what we are really trying to do is protect data from uncontrolled concurrent access.

Whether an object needs to be thread-safe depends on whether it will be accessed from multiple threads. This is a property of how the object is used in a program, not what it does. Making an object thread-safe requires using synchronization to coordinate access to its mutable state; failing to do so could result in data corruption and other undesirable consequences

By shared, we mean that a variable could be accessed by multiple threads;

multiple:与等于 n多个。variable:变量(变来变去的,百变怪)

by mutable, we mean that its value could change during its lifetime.

during its lifetime 在生命周期内/存活周期内等

这两句都是解释前面这个单词在本文的意思。

We may talk about thread safety as if it were about code, but what we are really trying to do is protect data from uncontrolled concurrent access.

我们讨论的线程安全性好像是关于代码的,但是我们真正要做的,是在不可控制的并发访问中保护数据

这句话是重点,编写线程安全的代码,真正要做的,其实是对object’s state的并发安全。而不是所有代码。

在工作中,分辨出哪些是常规代码,哪些是需要并发的,具体仔细到某一段逻辑或字段。

This is a property of how the object is used in a program, not what it does.

对象的状态是由其在程序中的使用方式决定的,而不是定义其目的或功能。

换句话说,对象的状态是指存储在其状态变量中的值,在对象被操作或与之交互时可以随着时间变化。状态表示对象在任何给定时刻的当前数据快照。

另一方面,对象的行为是指其可以执行的操作或方法,以及它对方法调用的响应方式。行为由对象的方法和其实现决定。

这句话强调了对象的状态是如何在程序执行中被使用、修改或访问而产生影响的,而行为则关注对象能做什么以及它在方法调用时如何响应。

总而言之,这句话强调了对象状态(由数据决定)与对象行为(由方法决定)之间的区别,并强调了对象的状态是由其在程序中的使用方式所影响的。

Making an object thread-safe requires using synchronization to coordinate access to its mutable state; failing to do so could result in data corruption and other undesirable consequences.

确保对象的线程安全性需要使用同步机制来协调对其可变状态的访问;如果不这样做,可能会导致数据损坏和其他不良后果。

当多个线程同时访问一个对象的可变状态时,如果没有适当的同步机制来保证线程间的协调,可能会发生以下问题:

  • 竞态条件(Race condition):多个线程同时修改对象的状态,导致结果依赖于执行的顺序,可能产生不确定的结果。
  • 数据不一致(Data inconsistency):多个线程同时读取和修改对象的状态,导致数据出现错误或不一致的情况。
  • 内存可见性问题(Memory visibility problem):多个线程在各自的缓存中保存对象的副本,没有及时将修改后的值刷新到主内存,导致其他线程无法看到最新的状态。

没完待续……

相关文章
|
6天前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
|
5天前
|
安全 Java 开发者
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
|
5天前
|
Java 开发者
Java多线程编程的艺术与实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的技术文档,本文以实战为导向,通过生动的实例和详尽的代码解析,引领读者领略多线程编程的魅力,掌握其在提升应用性能、优化资源利用方面的关键作用。无论你是Java初学者还是有一定经验的开发者,本文都将为你打开多线程编程的新视角。 ####
|
4天前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
|
7天前
|
安全 Java 开发者
Java多线程编程中的常见问题与解决方案
本文深入探讨了Java多线程编程中常见的问题,包括线程安全问题、死锁、竞态条件等,并提供了相应的解决策略。文章首先介绍了多线程的基础知识,随后详细分析了每个问题的产生原因和典型场景,最后提出了实用的解决方案,旨在帮助开发者提高多线程程序的稳定性和性能。
|
1月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
45 1
C++ 多线程之初识多线程
|
28天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
19 3
|
28天前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
17 2
|
28天前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
29 2
|
28天前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
34 1