原先多线程并发编程的学习笔记和代码整理一下贴上来。
---------------------------------
原子操作
一、什么是原子操作
原子操作是不能被线程调度机制中断的操作。一旦操作开始,它一定可以在可能发生的上下文切换之前(切换到其他线程执行)执行完毕。
原子操作可以应用于除long和double之外所有基本类型之上的简单操作。对于读取和写入除long和double之外的基本类型变量这样的操作,可以保证它们会被当作不可分的操作来操作内存。但64位的long和double读取和写入会被当作2个分离的32位操作来执行,这就产生一个读取和写入操作中间发生上下文切换,从而导致不同任务看到不正确的结果。
当定义long和double时,如果使用volatile,就会获得原子性。声明为volatile的域会立即写入主存中,而读取操作就发生在主存中。
多个线程同时访问某个域,那么这个域就应该是volatile的,否则这个域就应该只能由同步来访问。
但如果一个域的值依赖于它先前的值(例如计数器),或者一个域的值依赖于别的域值限制,volatile就无法正常工作。所以第一选择仍是使用synchronized关键字。
二、java.util.concurrent.atomic
从javase5开始,新加入了java.util.concurrent.atomic包, JDK文档中描述为:
类的小工具包,支持在单个变量上解除锁的线程安全编程。事实上,此包中的类可将volatile值、字段和数组元素的概念扩展到那些也提供原子条件更新操作的类。
在atomic包中提供了原子性变量类如AtomicBoolean、AtomicInteger、AtomicLong和AtomicReference等。
使用原子性变量类可以去除同步代码,但原子性变量类是被用来设计实现java.util.concurrent中的类,因此只有在特殊情况下再使用它们,一般常用于性能调优。
下面是一个对AtomicInteger的简单测试:
public class AtomicIntegerTest implements Runnable{ private AtomicInteger ait = new AtomicInteger(0); private void increment(){ ait.addAndGet(2); } private int get(){ return ait.get(); } @Override public void run() { while(true){ //每个线程都循环累加 increment(); try{ TimeUnit.MILLISECONDS.sleep(200); }catch(Exception e){ e.printStackTrace(); } } } public static void main(String[] args) throws Exception { ExecutorService es = Executors.newCachedThreadPool(); AtomicIntegerTest task = new AtomicIntegerTest(); for(int i=0;i<5;i++){ es.submit(task); } TimeUnit.SECONDS.sleep(1);//保证5个任务都已经启动 while(true){ int value = task.get(); if(value%2 != 0){ System.out.println("error value!"); System.exit(0); }else{ System.out.println("value:"+task.get()); } TimeUnit.MILLISECONDS.sleep(500); } } }
上面的示例程序中,首先创建了一个线程池,开启5个线程,每个线程都循环对原子性变量AtomicInteger累加2,同时循环读取AtomicInteger的值,如果该值%2!=0的话,则说明出现了非原子性操作,程序停止,但本程序会一直运行下去打印出value的值。同时注意increment方法并没有加锁。
相关推荐
│ 高并发编程第二阶段08讲、并发编程的三个重要概念,原子性,可见性,有序性.mp4 │ 高并发编程第二阶段09讲、指令重排序,happens-before规则精讲.mp4 │ 高并发编程第二阶段10讲、volatile关键字深入详解.mp4...
│ 高并发编程第二阶段08讲、并发编程的三个重要概念,原子性,可见性,有序性.mp4 │ 高并发编程第二阶段09讲、指令重排序,happens-before规则精讲.mp4 │ 高并发编程第二阶段10讲、volatile关键字深入详解.mp4...
在开始探讨CAS之前,我们首先简要回顾一下并发编程的一些基本概念。 - **进程**:是计算机中的一个执行单元,它拥有独立的地址空间,是操作系统进行资源分配和调度的基本单位。 - **线程**:是进程内的一个执行单元...
《Java并发编程实践》是Java开发者必读的经典之作,由Brian Goetz等多位专家共同撰写。这本书深入浅出地探讨了Java平台上的并发问题,帮助读者理解和掌握如何编写高效、可靠且可维护的多线程应用程序。以下是该书...
JUC 中包括了各种锁机制、原子变量、并发集合类、线程池、异步回调等多种机制,涵盖了 Java 并发编程的多个方面。 进程和线程回顾 在 Java 中,进程(Process)和线程(Thread)是两种不同的并发编程模型。进程是...
课程 Go语言基础 Day01 初识Go语言 开发环境搭建 第一个程序 基础语法 ...锁和原子操作 CSP并发设计模式 并发注意事项 作业 Day11 互联网协议介绍 TCP编程 UDP编程 实战: Socket代理 HTTP与WebSocket
第1讲:学习的要义 第2讲:Netty宏观理解 第3讲:Netty课程大纲深度解读 第4讲:项目环境搭建与Gradle配置 第5讲:Netty执行流程分析与重要组件介绍 ...第92讲:精通并发与Netty课程总结与展望
C++程序员需要理解如何使用原子操作和内存模型来确保跨核心的数据一致性,避免“欧洲机架延迟效应”。 3. **线程同步开销**:在多线程环境中,为了保证数据安全,需要使用互斥量、条件变量等同步机制。然而,这些...
在Java中,`java.util.concurrent`包提供了大量的工具类和接口,使得开发人员可以更方便地进行并发编程。 ##### 3.1 Executor框架 `java.util.concurrent.Executor`框架提供了一种灵活的方式来创建线程池,常见的...
对于那些希望快速掌握 Java 并发编程基础概念的学习者来说,这是一篇非常有价值的文章。 #### 二、Java 并发工具库 (Java Concurrency Utilities) Java 并发工具库是 Java 平台标准版(Java SE)的一部分,自 Java...
7. **网络与分布式系统**:操作系统在多计算机环境中的作用,如网络协议、Socket编程、分布式文件系统和负载均衡策略。 8. **死机恢复与事务处理**:在系统崩溃时如何保持数据一致性,以及事务的ACID属性(原子性、...
在PHP和MySQL的应用场景中,高并发环境下的...对于想要进一步学习的读者,可以参考相关的PHP+MySQL数据库操作教程,例如PHP+MySQL数据库操作入门、面向对象编程、数组操作、字符串处理以及数据库操作技巧汇总等资料。
在Java编程中,多线程环境下常常会遇到并发问题,特别是在进行共享数据的修改时。本文将探讨Synchronized关键字在解决并发控制中的作用及其使用方式。 首先,让我们回顾一下问题的背景:在给出的示例代码中,创建了...
- **1.1 简短的历史回顾**:这部分简单回顾了并发编程的发展历史,强调了现代计算机系统对并发处理的需求。 - **1.2 线程的好处**: - **1.2.1 利用多处理器**:介绍如何通过多线程编程来提高程序性能,尤其是在...
- **semop() 操作**:展示了如何使用 semop() 函数对信号量进行原子操作。 - **销毁信号量**:说明了如何释放不再使用的信号量资源。 - **示例程序**:提供了一些实用的示例代码,用于演示信号量的使用方法。 - **...