上一篇文章说的是,避免多个线程在同一时间访问对象中的同一数据,这篇文章来详细说说共享和发布对象。
在没有同步的情况下,我们无法预料编译器、处理器安排操作执行的顺序,经常会发生以为“一定会”发生的动作实际上没有发生。可以用一些简单的方法来避免这个问题。
在 Java 中,如果不是64位版本的,JVM 会把 double 或者 long 的读和写划分在两个 32 位中,这样一来,在多线程中,没有声明是 volatile 的 double 或者 long 也是不安全的。
锁是同步和互斥的,同样也是内存可见的。为了避免出现读到过期的数据,读和写的线程都要使用公共的锁进行同步。
volatile 是一种弱同步,只能保证可见性,而不能保证原子性。(为了安全,可以理解成 volatile 基本上只能使 boolean 的值原子化,像自增这种操作是不能被 volatile 原子化的)在确保 volatile 变量所引用状态的可见性、标识重要的生命周期事件(初始化或者关闭)的时候可以用,其他的时候最好不要用。下面数绵羊的代码就是一种典型的应用:
volatile boolean asleep; ... while(!asleep) { count(); }
如果有其他的线程修改了 asleep, 让它变成 true 了,那么就会跳出循环。
不要在构造函数中启动线程,有可能造成溢出。用单独的 start() 或者 init() 启动线程
对于只在一个线程内使用的数据就没必要同步了,对于可以用 volatile(只有一个线程写入的变量),或者可以用栈限制:
public in loadTheArk(Collection<Animal> cadidates) { SortedSet<Animal> animals; int numPairs = 0; Animal candidate = null; // new 了一个集合来装 cadidates,避免溢出 animals = new TreeSet<>(new SpeciesGenderComparator()); animals.addAll(candidates); ... // count numPairs }
也可以用更规范的方法 ThreadLocal 把线程和持有数值的对象关联在一起。但是这种方法开销比较大。
不可变的对象是线程安全的,它必须满足:
- 它的状态在创建后不能被修改
- 所有的域都是 final 的
- 被正确的创建(创建期间没有发生 this 引用的溢出)
对象发布时,应该使用同步。但是对于不可变对象来说,可以不用同步。为了安全的发布对象,可以:
- 静态初始化对象的引用
- 把它的引用存储到 volatile 域或者 AtomicReference
- 把它的引用存储到正确创建对象的 final 域中
- 把它的引用存储到由正确锁保护的域中
如果对象本身是可变的,但是发布之后状态不会被修改,那么就在发布的时候对所有线程可见,之后线程访问这个对象就不需要额外的同步了。如果后续状态会被改变,那么必须是线程安全或者锁保护的。
相关推荐
Java并发编程是Java开发中的重要领域,特别是在多核处理器和分布式系统中,高效地利用并发可以极大地提升程序的性能和响应速度。以下是对标题和描述中所提及的几个知识点的详细解释: 1. **线程与并发** - **线程*...
Java并发编程是Java开发中的重要领域,特别是在多核处理器和分布式系统中,高效地利用并发可以极大地提升程序的性能和响应速度。这份“java并发编程内部分享PPT”显然是一个深入探讨这一主题的资料,旨在帮助开发者...
#### 一、Java并发概述 自Java诞生之初,其设计者就赋予了该语言强大的并发处理能力。Java语言内置了对线程和锁的支持,这使得开发者能够轻松地编写多线程应用程序。本文旨在帮助Java开发者深入理解并发的核心概念...
《Java并发编程实践》是一本深入探讨Java多线程编程的经典著作,由Brian Goetz、Tim Peierls、Joshua Bloch、Joseph Bowles和David Holmes等专家共同编写。这本书全面介绍了Java平台上的并发编程技术,是Java开发...
3.5.6 安全地共享对象 第4章 对象的组合 4.1 设计线程安全的类 4.1.1 收集同步需求 4.1.2 依赖状态的操作 4.1.3 状态的所有权 4.2 实例封闭 4.2.1 Java监视器模式 4.2.2 示例:车辆追踪 4.3 线程安全性的...
Java并发编程是Java开发者必须掌握的关键技能之一,它涉及到如何在多线程环境中高效、安全地执行程序。并发编程能够充分利用多核处理器的计算能力,提高应用程序的响应速度和整体性能。《Java编程并发实战》这本书是...
《Java并发实战》是一本深度剖析Java并发编程的权威指南,旨在帮助开发者高效地理解和解决多线程环境下的编程挑战。文档清晰明了,配备有详细的目录,使得学习过程更为顺畅,避免了在查找信息上浪费时间。标签“Java...
1. 线程安全性:确保共享对象在并发访问时,能够保持一致性和正确性。 2. 内存可见性:确保一个线程修改的变量能够对其他线程立即可见。 3. 锁的使用:如何合理使用内置锁或显式锁(如ReentrantLock)来管理同步。 4...
本篇文章将深入探讨Java并发编程的相关知识点,主要基于提供的两个文件——"Java并发编程实战(中文版).pdf"和"Java Concurrency in Practice.pdf"。 1. **线程与并发** - **线程基础**:Java中的线程是并发执行...
本资料“Java并发编程设计原则和模式”深入探讨了如何在Java环境中有效地进行并发处理,以充分利用系统资源并避免潜在的并发问题。 一、并发编程基础 并发是指两个或多个操作在同一时间段内执行,但并不意味着这些...
在Java并发编程中,通常会涉及多个线程共享资源并同时运行的情况,这种情况下就需要理解和掌握并发与并行的基本概念。 #### 1.2 Java并发编程的核心类库 - **java.util.concurrent**:提供了大量的并发工具类和容器...
Java并发编程是Java开发中的重要领域,特别是在大型分布式系统、多线程应用和服务器端程序设计中不可或缺。这个资源包“Java并发编程从入门到精通源码.rar”显然是为了帮助开发者深入理解并掌握这一关键技能。它包含...
### Java并发编程实践知识点详解 #### 一、Java并发编程基础 ##### 1.1 并发与并行概念区分 在Java并发编程实践中,首先需要理解“并发”与“并行”的区别。“并发”指的是多个任务同时进行,但实际上可能是在多...
Java并发编程是Java高级特性之一,它允许开发者编写能够同时执行多个任务的程序,这对于提高应用程序的性能至关重要。下面将详细探讨Java并发编程中的关键概念、技术及实践技巧。 ### 一、Java并发编程基础 #### ...
《Java并发编程实践》这本书是Java开发者深入理解并发编程的重要参考资料。并发和多线程是现代计算机系统中不可或缺的部分,特别是在Java这样的多线程支持语言中。本书详细介绍了如何在Java环境中有效地设计和实现...
《java并发编程实战》读书笔记-第3章-对象的共享,脑图形式,使用xmind8制作 包括可见性、发布与逸出、线程封闭、不可变性、安全发布等内容
《Java并发编程艺术》这本书是Java开发者深入理解多线程编程的重要参考资料。它全面而深入地探讨了Java平台上的并发编程技术,对于提升程序性能、优化系统资源利用以及解决多线程环境中的复杂问题有着极大的帮助。...
Java 并发处理方式 在多线程编程中,线程之间的并发访问可能会导致资源争夺和数据不一致的问题。 Java 提供了多种方式来解决并发问题,包括使用锁、同步代码块和 volatile 变量等。 一、什么是并发问题? 并发...