前面说了如何管理对共享、易变状态的数据的状态的访问,《JAVA并发编程》第三章主要介绍共享和发布可以被多线程安全访问的对象,使用了java.util.concurrent包下的类为基础,创建线程安全的类和构建安全的并发应用程序。
synchronized不仅仅与操作原子性和关键区域定界相关,它还有个重要却不明显的作用——内存可见性。同步不仅仅是防止线程修改正在被别的线程使用的对象状态,还可以保证当一个线程修改了对象状态后,其他线程可以看到状态的更新。通过显示的同步或利用内置的同步的类库,可以保证发布的对象是线程安全的。
可见性
当一个线程对对象状态进行读操作,另一个线程对该对象状态进行写操作时,如果没有线程同步,则无法保证读对象的线程能即时的读取到写对象更新后的值。
package com.zyp.test.concurrent; public class NoVisibility { private static boolean ready;//默认值为false private static int number; private static class ReaderThread extends Thread { public void run() { while (!ready) Thread.yield(); System.out.println(number); } } public static void main(String[] args) { new ReaderThread().start(); number = 42; ready = true; System.out.println("end"); } }
这段代码中有两个线程,一个主线程和一个读线程都要反问number和ready。主线程启动读线程后,将ready置为true。读线程一直循环,直到发现ready为true后,打印number的值。看起来读线程打印结果:
1:可能是明显的42,
2:也可能打印出0,
3:也可能永远不停止。
因为没有适当的同步,不能保证主线程写了number和ready一定对读线程是可见的。上面读线程可能永远不停止,因为ready可能对读线程永远不可见。上面可能打印出0,跟重排序有关。
重排序(reordering):在一个线程中的方法的执行顺序并不保证与代码中顺序一致。在没有同步的情况下,java内存模型(JMM)允许编译器重新排序操作,以获取多处理器带来的更多好处。
重排序后,编译器后的代码可能先执行ready的赋值再执行number的赋值。
相关推荐
线程,同步与锁————Lock你到底锁住了谁?.htm
当一个程序中存在多个并发执行的线程时,它们可能需要共享数据或者互相通知事件的发生,这就需要线程间通信机制。下面将详细讨论几种常见的线程间通信方式。 1. 使用全局变量进行通信 全局变量是所有线程都能访问的...
在Python编程中,进程和线程是并发执行任务的基础概念,它们允许程序同时处理多个任务,提高系统的效率和响应速度。下面将详细解释这些概念及其相关的工具和机制。 ### 进程 进程是计算机中运行的程序的一个实例,...
【Java初学者适用——Java实例大全】是一份专为初学者设计的教程资源,它涵盖了大量实际编程案例,旨在帮助新手快速掌握Java编程语言。在Java的世界里,实践是掌握知识的关键,通过实例学习能够更好地理解和应用理论...
对于静态成员、全局变量和共享对象,必须确保它们在多线程环境中的访问是安全的。使用`volatile`关键字、`Interlocked`类或其他同步机制可以帮助实现线程安全。 8. Task并行库(TPL): .NET Framework 4.0引入了...
第11章 实例257——使用Win32 ... 实例274——三种方法实现启动其他的应用程序 实例275——使用剪贴板实现程序间的数据交换 实例276——通过内存映射实现进程间的数据交换 实例277——通过消息机制实现进程间的通信
饿汉式是在类加载时就完成了初始化,因此类加载比较慢,但获取实例的速度快,且线程安全。代码如下: ```java public class Singleton { private static final Singleton INSTANCE = new Singleton(); private ...
《Visual C++开发GIS系统——开发实例剖析guangpan》这本书着重讲解了如何利用Microsoft的Visual C++编程环境来开发地理信息系统(GIS)的应用程序。GIS是计算机科学与地理学的交叉领域,它用于采集、存储、管理和...
1. SpringBoot 自定义线程池以及多线程间的异步调用(@Async、@EnableAsync) 2.Java多线程之定时任务 以及 SpringBoot多线程实现定时任务 3.@EnableScheduling 与 @Scheduled
1. **避免使用实例变量**:尽可能使用局部变量,局部变量只存在于方法的执行上下文中,不会被多个线程共享,因此不存在线程安全问题。 2. **使用同步控制**:通过`synchronized`关键字对关键代码块或方法进行同步,...
Java线程安全是多线程编程中的一个关键概念,它涉及到多个线程访问共享资源时可能出现的问题。在Java中,线程安全问题通常与并发、内存模型和可见性有关。Java内存模型(JMM)定义了如何在多线程环境下共享数据的...
易语言实例模块——多线程模块.e
Linux 下 C 语言多线程编程实例 Linux 下的多线程编程是一种非常重要的技术,在实际应用中有非常广泛的应用范围。多线程编程可以大大提高程序的执行效率和响应速度。但是,多线程编程也存在一些复杂性,例如线程...
本文将基于"java 多线程并发实例"这个主题,深入探讨Java中的多线程并发概念及其应用。 首先,我们要了解Java中的线程。线程是程序执行的基本单元,每个线程都有自己的程序计数器、虚拟机栈、本地方法栈,而共享堆...
本资源"安卓Android源码——项目实例商业项目源代码.zip"提供了一个实际的商业项目源代码,对于学习Android开发者来说,这是一个宝贵的实践机会,能够深入理解Android系统的运行机制以及应用程序的构建过程。...
本资源包含六个C#.NET多线程的实例,涵盖了多线程的基本使用到更高级的概念,如线程互斥。以下是这些实例可能涉及的关键知识点: 1. **线程创建**:C#中创建线程主要有两种方式,一是通过`System.Threading.Thread`...
2. **实例2**:使用`Mutex`,展示如何确保同一时间只有一个线程访问共享资源。 3. **实例3**:`Semaphore`应用,限制同时访问数据库连接池的线程数量。 4. **实例4**:使用`Monitor`实现的线程同步,防止数据竞争。 ...
线程安全队列的接口文件如下: #include template class threadsafe_queue { public: threadsafe_queue(); threadsafe_queue(const threadsafe_queue&); threadsafe_queue& operator=(const threadsafe_queue&...
在多线程环境中,事件处理通常在引发事件的线程上运行,因此,如果一个线程修改了UI控件的状态,而另一个线程尝试处理相关事件,可能会导致线程不安全。使用适当的同步机制可以解决这个问题。 "资源管理器"可能涉及...