volatile

5.互联网大厂高频面试题-volatile

▼魔方 西西 提交于 2020-03-05 13:34:02
请谈谈你对volatiel的理解? 文章目录 volatile是什么 JMM内存模型之可见性 volatile是什么 首先JUC指的是java的三个包: 首先这个关键字在你日常的单线程工作环境下你是用不到的。 它的3大特性: JMM内存模型之可见性 来源: CSDN 作者: 余生的观澜 链接: https://blog.csdn.net/qq_25310669/article/details/104665678

并发数据结构:迷人的原子

为君一笑 提交于 2020-03-05 01:47:21
随着多核CPU成为主流,并行程序设计亦成为研究领域的热门。 要想利用多核/多路CPU带来的强大功能,通常使用多线程来开发应用程序。但是要想拥有良好的硬件利用率,仅仅简单的在多个线程间分割工作是不够的。还必须确保线程大部分时间在工作,而不是在等待工作或等待锁定共享数据结构。 在不止一个线程访问共享数据时,所有线程都必须使用同步。如果线程间不进行协调,则没有任务可以真正并行,更糟糕的是这会给程序带来毁灭性的错误。 现在让我们来看一下在.NET和D语言中的标准同步手段-锁定。.NET下我们使用lock关键字,而D语言则使用 synchronized关键字。它们在Windows下均使用临界区(Critical Section)来实现,而在Linux下则使用互斥锁(Mutex)来实现。不论其如何实现,它们均强制实行互斥,来确保持有锁的线程对共享数据的独占访问权,以及当其他线程持有锁时,可以看到其对共享数据的修改。 简而言之,在基于锁的多线程编程中,任何针对共享数据,且有可能导致竞争条件的操作,我们都得将其改为原子操作(即连续的,不允许被打断的步骤;上面的lock/ synchronized 关键字就是我们实现原子操作的手段)。只要我们的线程持有锁,就不必担心其他线程会进来捣乱。 这听起来似乎很不错,我们只要加锁/解锁就可以为所欲为了。然而正是这种为所欲为的事实带来了问题

多线程编程学习十二(原子性、可见性与有序性)

半城伤御伤魂 提交于 2020-03-04 10:19:11
原子性 原子(atom)指化学反应不可再分的基本微粒,原子在化学反应中不可分割。原子操作指的是不可分割的整体,多线程的 原子性 指的是没有其他线程能够中断或检查正在原子操作中的变量。 从内存模型来看,直接保证的原子性变量操作包括 read、load、assign、use、store 和 write,我们大致可以认为基本数据类型的访问读写是具备原子性的。 从应用场景来看,JVM 保证原子性操作的主要有以下方式: synchronized 关键字。锁操作,基于 monitorenter 和 monitorexit 字节码指令,保证同步块只有单一线程执行。 AQS 锁机制。比如 ReentrantLock、ReentrantReadWriteLock 等,保证同步块只有单一线程执行。 CAS 实现。比如 java.util.concurrent.atomic 包中的诸多实现。 volatile 关键字。修饰变量,轻量锁机制,仅能保证对单个变量的操作具有原子性,复合操作不具备原子性。 可见性 可见性 是指当一个线程修改了共享变量的值,其他线程能够立即得知这个修改。 从应用场景来看,JVM 保证可见性主要有以下方式: volatile 关键字,它是如何保证可见性的呢? 当对 volatile 变量写的时候,会将当前处理器缓存行的数据写回到系统内存。 当对 volatile 变量读的时候

JAVA JUC

非 Y 不嫁゛ 提交于 2020-03-04 03:55:54
文章目录 JAVA JUC 一、Volatile 关键字-内存可见性 1、java线程的6种状态Thread.state: 2、JAVA多线程:判断 干活 改标志位加唤醒通知(详见Thread.start()方法) 3.一共两个线程 (1)同步锁:synchronized关键字,使两个线程同步 (2)Volatile关键字 (3)Volatile与Scnchronized比较 二、原子变量与CAS算法 1、i ++ 的原子性问题:i++ 的操作实际上分为三个步骤“读-改-写” 2、原子变量:JDK1.5以后 java.util.concurrent.atomic 包下提供了常用的原子变量 (1)原子变量特性 (2)原子性的解决过程:(先读取内存值,再进行比较,再进行赋值和写入) (3)原子变量的使用: 三、模拟CAS算法 四、ConcurrentHashMap锁分段机制 1、hashmap和hashtable区别: 2、ConCurrentHashMap采用“锁分段”机制 3、CopyOnWriteArrayList/CopyOnWriteArraySet : “写入并复制” 4、CountDownLatch(==闭锁==,在完成某些运算是,只有其他所有线程的运算全部完成,当前运算才继续执行) 四、创建执行线程的方式三:实现Callable接口 五、Lock同步锁 1

java中volatile关键字的含义

牧云@^-^@ 提交于 2020-03-03 18:55:51
转自:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉。 Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 和 volatile 关键字机制。 synchronized 同步块大家都比较熟悉,通过 synchronized 关键字来实现,所有加上synchronized 和 块语句,在多线程访问的时候,同一时刻只能有一个线程能够用 synchronized 修饰的方法 或者 代码块。 volatile 用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。volatile很容易被误用,用来进行原子性操作。 下面看一个例子,我们实现一个计数器,每次线程启动的时候,会调用计数器inc方法,对计数器进行加一 执行环境——jdk版本:jdk1.6.0_31 ,内存 :3G cpu:x86 2.4G public class Counter { public static int count = 0; public static void inc() { //这里延迟1毫秒,使得结果明显 try { Thread

C# MODBUS协议上位机程序

核能气质少年 提交于 2020-03-03 17:25:10
C#写了一款上位机监控软件,基于MODBUS_RTU协议。 软件的基本结构: 采用定时器(Timer控件)为时间片。 串口采用serialPort1_DataReceived中断接收,并进行MODBUS格式判断。 把正确接收的数据取出,转换为有特定的结构体中。 数据通过时间片实时刷新。 MODBUS协议(这里不介绍了,网上有很多的权威资料)。   串口接收问题 这里采用的是MODBUS_RTU协议,是没有回车等明显的结束符的哈。所以在C#也不可以用serialPort1.ReadLine来读取。我用的是serialPort1.BytesToRead先读缓冲区中的数据个数,再通过个数据读数据。这样在用串口软件测试的时候确实很有用,再随之问题又出现了。下位机传上来的数据长度高出8个,就会分断接收。即接收到的两次的长度,第一次是8个,然后再接收到后面的。 原因是因为软件没有接收完一整帧数据后就进行了中断。解决方法:在中断中加入线程阻塞方法,然后再读取串口中的数据。   发送读数据和发送写数据的结构 写了多个MODBUS协议的上位机后,总结了些经验,并将这部分程序封装在一个类中。 使用时只需对其接口函数调用即可,有很强的移植性。在写软件时不用再在协议这部分花太多的时间。 基本的使用方法在注释中。程序总体感觉 可能过于臃肿,希望各位大神批评指点。 以下是源代码: 1 /* 2 *

java多线程总结四:volatile、synchronized示例

て烟熏妆下的殇ゞ 提交于 2020-03-03 13:56:48
1、synchronized保证同步 先看一个生成偶数的类 [java] view plain copy <span style= "font-size:16px;" > package demo.thread; /** *这是一个int生成器的抽象类 * */ public abstract class IntGenerator { private volatile boolean canceled = false ; public abstract int next(); public void cancel() { canceled = true ; } public boolean isCanceled() { return canceled; } } </span> [java] view plain copy <span style= "font-size:16px;" > /* * 产生偶数 */ class EvenGenerator extends IntGenerator { private int currentEvenValue = 0 ; String s = "" ; @Override public int next() { <span style= "color:#ff0000;" > synchronized </span>(s) { +

15_volatile

£可爱£侵袭症+ 提交于 2020-03-03 13:48:05
【volatile概念】 volatile关键字的主要作用是是变量在多个线程间可见。 【注意】   在java中,每一个线程都会有一块工作内存区,其中存放着所有线程共享的主内存中的变量的拷贝。当线程执行时,他在自己的工作内存区中操作这些变量。为了存取一个共享的变量,一个线程通常会先获取并去清除它的内存工作区,把这些共享变量从所有线程的共享内存区中正确地装入到他自己所在的工作内存区中,当线程解锁时保证该内存区中变量的值写回到共享内存中。   一个线程可以执行的操作有:使用(use)、赋值(assign)、装载(load)、存储(store)、锁定(lock)、解锁(unlock)。   而主内存可以执行的操作有:读(read)、写(write)、锁定(lock)、解锁(unlock),每个操作都是原子的。   volatile的作用就是强制线程到主内存(共享内存)里去读取变量,而不去线程工作内存区里去读取,从而实现了多个线程间的变量可见。也就是满足线程安全的可见性。 【线程执行流程图】 【volatile可见性的例子】 package com.higgin.part6; public class MyThread extends Thread{ /** * 加与不加volatile * 不加volatile:main线程中将isRunning设置为flase

6.并发编程--volatile

不问归期 提交于 2020-03-03 13:47:05
并发编程--volatile volatile-说明 volatile关键字的作用是变量在多个线程可见; volatile 关键字是非原子性的 要是实现原子性操作,建议使用atomic类的系列对象:支持原子性操作(注意atomic类只保证本身方法的原子性,并不保证多次操作的原子性) 1. volatile : volatile关键字的作用是变量在多个线程可见; 示例: RunThread.java 说明: 在Java中,每个线程都会有一个工作内存区域,其中存放所有线程共享的主内存中的变量的值得拷贝。当线程执行的时候,在自己的工作内存区域中操作这些变量。为了存取一个共享的变量,一个线程通常先获得锁定并清除当前线程的内存工作区域,把这些共享变量从所有线程的共享内存区域中正确的装入到本身所以在的工作内存区域中,当线程解锁是保证该工作内存中的变量的值写会到共享内存区域中。 * 一个线程可以执行的操作有:使用(use),赋值(assgin),装载(load),存储(store),锁定(lock),解锁(unlock); * 主内存中可以执行的操作有:读(read),写(write),锁定(lock),解锁(unlock); 每个操作都是原子性的。 * volatile 的作用就是强制线程到主内存(共享内存)中去读取变量,而不是去线程工作内存区域里去读取,从而实现了多个线程间的变量可见