精华内容
下载资源
问答
  • 多线程常量
    千次阅读
    2018-04-15 19:24:53

    做过多线程开发的猿友们应该会遇到这两个问题

    首先,理解一下可见性:

     

    线程在修改主存变量的时候会先拷贝一份到自己的线程栈中去处理,每个线程都有自己的空间,相互是独立的,在变量修改完成到写入主存中,这个过程对其它线程是不可见的。(这里不明白的话可以看一下JVM内存结构及线程间的通信)

    那么问题来了 不可见会如何?数据的一致性会被打乱,程序出bug,A线程改了变量c的值,B线程读到的却是c原来的值(其实想要的是A线程改后的值)

    解决办法:

    使用synchronized(低效,使用悲观锁)、volatile修饰符来保证变量的可见性

     

    Jdk5后提出了atomic 原子操作也可以保证可见性(高效且不需要使用同步,基于CAS)

    Volatile和synchronized区别

    Volatile只是保证变量可见性,并不能确保原子性,它是依赖CPU提供的特殊指令内存屏障指令来控制可见性,被Volatile修饰的成员变量在被线程访问时在读操作前会强行插入一条内存屏障读指令强行从主存中读取(让高速缓存中的数据失效,重新从主内存加载数据),变量在被线程修改时会在写指令之后插入写屏障让写入缓存的最新数据写回到主内存

    不能确保原子性,是因为如果A线程和B线程同时读取到变量a值,A线程修改a后将值刷到主存、同时B线程也修改了a的值并刷到主存,这时候B线程就覆盖了A线程修改操作。

    Synchronized是通过对线程加锁(独占锁)控制线程同步,被Synchronized修饰的内存只允许一个线程访问

    Cas理解(乐观锁基于CAS)

    有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做,重新再尝试。注意ABA情况

     

     

     

    更多相关内容
  • 多线程三大特性——原子性

    千次阅读 2022-01-10 20:33:40
    如果一个操作是原子性的,那么多线程并发的情况下,就不会出现变量被修改的情况。 比如 a=0;(a非long和double类型) 这个操作是不可分割的,那么说这个操作是原子操作。再比如:a++; 这个操作实际是a = a + 1;...

    概念

    原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行原子性就是指该操作是不可再分的。

    如果一个操作是原子性的,那么多线程并发的情况下,就不会出现变量被修改的情况。

    比如 a=0;(a非long和double类型) 这个操作是不可分割的,那么说这个操作是原子操作。再比如:a++; 这个操作实际是a = a + 1;是可分割的,所以他不是一个原子操作。

    非原子操作都会存在线程安全问题,需要使用同步技术(sychronized)来让它变成一个原子操作。一个操作是原子操作,那么称它具有原子性。java的concurrent包下提供了一些原子类,比如:AtomicInteger、AtomicLong、AtomicReference等。

    由Java内存模型来直接保证的原子性变量操作包括read、load、use、assign、store和write六个,大致可以认为基础数据类型的访问和读写是具备原子性的。

    如果应用场景需要一个更大范围的原子性保证,Java内存模型还提供了lock和unlock操作来满足这种需求,尽管虚拟机未把lock与unlock操作直接开放给用户使用,但是却提供了更高层次的字节码指令monitorentermonitorexit来隐匿地使用这两个操作,这两个字节码指令反映到Java代码中就是同步块—synchronized关键字,因此在synchronized块之间的操作也具备原子性。

    Java中的原子操作

    变量操作

    • 除了long和double 之外的基本数据类型(int byte boolean short char float)的赋值操作
    • 所有引用类型的reference的赋值操作,无论是32位还是64位机器。

    java对long和double的赋值操作是非原子操作!!long和double占用的字节数都是8,也就是64bits。

    在32位操作系统上对64位的数据的读写要分两步完成,每一步取32位数据。这样对double和long的赋值操作就会有问题:如果有两个线程同时写一个变量内存,一个进程写低32位,而另一个写高32位,这样将导致获取的64位数据是失效的数据。因此需要使用volatile关键字来防止此类现象。

    volatile本身不保证获取和设置操作的原子性,仅仅保持修改的可见性。但是java的内存模型保证声明为volatile的long和double变量的get和set操作是原子的。

    Atomic类

    java.concurrent.Atomic.*包中的所有类的原子操作。atomic包里面一共提供了13个类,分为4种类型,分别是:原子更新基本类型,原子更新数组,原子更新引用,原子更新属性,这13个类都是使用Unsafe实现的包装类。

    用原子操作类实现原子操作(原子操作类内部是使用CAS实现原子操作的)会有ABA问题。

    ABA问题解决思路:版本号。在变量前加版本号,每次变量更新时将版本号加1,A -> B -> A,就变成 1A -> 2B -> 3A。

    JDK5之后Atomic包中提供了AtomicStampedReference#compareAndSet来解决ABA问题。

    CAS锁优点

    • 性能角度:它执行多次的所消耗的时间远远小于由于线程所挂起到恢复所消耗的时间,因此无锁的CAS操作在性能上要比同步锁高很多;
    • 业务需求:业务本身的需求上,无锁机制本身就可以满足我们绝大多数的需求,并且在性能上也可以大大的进行提升。

    锁机制

    锁机制保证只有拿到锁的线程才能操作锁定的内存区域。synchronized锁定的临界区代码对共享变量的操作是原子操作。

    JVM内部实现了多种锁,偏向锁、轻量锁、互斥锁。不过轻量锁、互斥锁(即不包括偏向锁),实现锁时还是使用了CAS,即:一个线程进入同步代码时用自CAS拿锁,退出块的时候用CAS释放锁。

    CPU的原子操作

    CPU会自动保证基本的内存操作的原子性。CPU保证从内存中读写一个字节是原子的。即:当一个CPU读一个字节时,其他处理器不能访问这个字节的内存地址。对于复杂的内存操作如跨总线跨度、跨多个缓存行的访问,CPU是不能自动保证的。不过,CPU提供总线锁定和缓存锁定。

    总线锁

    利用LOCK#信号,当一个CPU在总线上输出此信号,其他CPU的请求会被阻塞,则该CPU可以独占共享内存。

    假如多个处理器同时读改写共享变量,这种操作(i++)不是原子的,操作完的共享变量的值会和期望的不一致。

    原因:多个处理器同时从各自缓存读i,分别 + 1,分别写入内存。要想保证读改写共享变量的原子性,必须保证CPU1读改写该变量时,CPU2不能操作缓存了该变量内存地址的缓存。
    总线锁就是解决此问题的。

    缓存锁(缓存一致性)

    缓存一致性机制阻止同时修改由两个以上CPU缓存的内存区域数据,当其他CPU回写已被锁定的缓存行数据时,会使缓存行无效

    同一时刻,其实只要保证对某个内存地址的操作是原子的即可,但总线锁定把CPU和内存间的通信锁住了。锁定期间,其他CPU不能操作其他内存地址的数据,所以总线锁定的开销比较大。目前CPU会在一些场景下使用缓存锁替代总线锁来优化。

    频繁使用的内存会被缓存到L1、L2、L3高速cache中,原子操作可直接在高速cache中进行,不需要声明总线锁。

    展开全文
  • 主要介绍了浅谈Java多线程编程中Boolean常量的同步问题,主要针对线程之间同步了不同的布尔对象的问题,需要的朋友可以参考下
  • Java多线程String的常量池特性

    千次阅读 2016-11-22 11:01:55
    在JVM中具有String常量池缓存的功能将...出现这样的情况是因为String的两个值都是AA,两个线程持有相同的锁,所以造成线程B不能执行。这就是String常量池所带来的问题。 这样实例化一个对象就持有两个不同的锁了。

    在JVM中具有String常量池缓存的功能

    这里写图片描述

    将synchronized(string)同步块与String联合使用时,要注意常量池带来的一些例外。

    这里写图片描述
    这里写图片描述

    出现这样的情况是因为String的两个值都是AA,两个线程持有相同的锁,所以造成线程B不能执行。这就是String常量池所带来的问题。

    这里写图片描述
    这里写图片描述

    这样实例化一个对象就持有两个不同的锁了。

    展开全文
  • 如何保证多线程的原子性

    千次阅读 2019-08-22 16:57:02
    原子性 定义: 原子是世界上的最小单位,具有不可分割性。...非原子操作都会存在线程安全问题,需要我们使用相关技术(比如sychronized)让它变成一个原子操作。一个操作是原子操作,那么我们称它具有原...

    原子性

    定义:

    原子是世界上的最小单位,具有不可分割性。比如 i=1,这个操作是不可分割的,那么我们说这个操作是原子操作。再比如:i++,这个操作实际是i= i + 1,包括读取i,i+1,将结果写入内存 三个操作,是可以分割的,所以他不是一个原子操作。非原子操作都会存在线程安全问题,需要我们使用相关技术(比如sychronized)让它变成一个原子操作。一个操作是原子操作,那么我们称它具有原子性。

    这句话的丰富含义有:

    1.原子操作是对于多线程而言的,对于单一线程,无所谓原子性。

    2.原子操作是针对共享变量的。

    3.原子操作是不可分割的。指访问某个共享变量的操作从其他任意线程来看是不可分割的。

    保证多线程原子性的方式:

      1. 加锁

        使用synchronized同步代码块保证线程的同步,从而保证多线程的原子性,但是加锁的话,就会使开销比较大。加锁和解锁是有消耗的。并且只要有加锁、解锁就会伴随着线程阻塞、线程唤醒,这样线程的切换也是消耗性能的。加锁本质上是将并发转变为串行来实现的,势必会影响吞吐量。

      2. CAS无锁算法

    CAS (比较与交换,Compare and swap)是一种有名的无锁算法, 即不使用锁的情况下实现多线程之间的变量同步。

    CAS包含 3 个参数:共享变量的原始值A、预期值B和新值 C。只有当A的值等于B,才能把A的值变成C。也就是说预期值B等于原始值A,说明共享变量没有被其他线程修改过,所以才允许更新新值,这样就保证了原子性!如果A不等于B,说明共享变量已经被其他线程修改过了,当前线程可以放弃此操作。

    基于这样的算法,CAS算法即使没有锁,也可以发现其他线程对当前线程的干扰,并进行恰当的处理。

    展开全文
  • 这是电梯的Java多线程应用程序。 尖端 所有的源代码文件都应使用GBK编码加载,否则某些图标可能会以错误的样式显示。 解释 有4个图像和5个类别。 图片 --------------- -------------- --------------- 已关闭....
  • 日常开发中如果用到多线程编程,也一定会涉及到线程安全问题 线程安全这个问题就不太好理解 正因为如此,程序猿们才尝试发明出更多的编程模型来处理并发编程的任务 例如:多进程、多线程、actor、csp、async+await、...
  • 常量池以及多线程

    2019-03-01 13:28:41
    常量池: 1:常量: final修饰的成员变量表示常量,值一旦给定就无法改变 final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量 2:静态常量池和运行时常量池: 静态常量池:即*....
  • 适合初学者使用,Java多线程技术实现矩阵乘积计算
  • 这个资源仅供参考!希望大家提提意见!希望大家支持支持!也我从别的地方找来的!
  • Java多线程学习(吐血超详细总结)

    万次阅读 多人点赞 2015-03-14 13:13:17
    本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。
  • Linux多线程

    千次阅读 多人点赞 2022-01-23 21:05:05
    文章目录Linux线程概念什么是线程线程的优点线程的缺点线程异常线程用途Linux进程VS线程进程和线程进程的线程共享关于进程线程的问题Linux线程控制POSIX线程库创建线程线程终止线程等待分离线程Linux线程互斥...
  • 可能与别的用到这些对象的地方产生冲突
  • 采用I/O复用技术select实现socket通信,采用多线程负责每个客户操作处理,完成Linux下的多客户聊天室! OS:Ubuntu 15.04 IDE:vim gcc make DB:Sqlite 3 Time:2015-12-09 ~ 2012-12-21 项目功能架构: 1. ...
  • Java 多线程编程基础(详细)

    万次阅读 多人点赞 2020-11-03 17:36:30
    Java多线程编程基础进程与线程多线程实现Thread类实现多线程Runnable接口实现多线程Callable接口实现多线程多线程运行状态多线程常用操作方法线程的命名和获取线程休眠线程中断线程强制执行线程让步线程优先级设定...
  • 多线程的安全问题

    千次阅读 2022-02-24 16:52:47
    多线程的环境下数据什么时候会存在线程安全的问题? 1.多线程并发 2.线程之间有共享数据 3.线程之间的共享数据有修改行为 如何解决线程安全的问题? 让线程不能并发,也就是让线程排队执行,这种机制被称为...
  • 多线程常见的面试题

    万次阅读 2020-09-16 16:21:58
    多线程常见的面试题: 1. 什么是线程和进程? 线程与进程的关系,区别及优缺点? 进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。 ...
  • Java并发(一):多线程干货总结

    千次阅读 2021-02-25 18:45:33
    一、进程 线程进程:一个进程来对应一个程序,每个进程对应一定的内存地址空间,并且只能使用它自己的内存空间,各个进程间互不干扰。进程保存了程序每个时刻的运行状态,这样就为进程切换提供了可能。当进程暂停时...
  • java 多线程 面试题整理(更新......)

    万次阅读 多人点赞 2021-11-30 16:23:06
    3、什么是同步执行和异步执行4、Java中实现多线程有几种方法?(较难)(1)继承Thread类(2)实现runable接口(3)实现Callable接口(创建FutureTask(Callable)对象)5、Future接口,Callable接口,FutureTask实现类的...
  • 多线程四大经典案例

    千次阅读 多人点赞 2022-04-11 16:32:17
    你会发现,当多线程时,这个样子由于没有原子性是有很大可能存在线程安全的问题的 因为我们这里是单例模型,就是这种存在唯一一份实例,而不能存在多份,而在多线程的情况下是会出现多份实例调用的情况的,下面我们...
  • C++11 多线程(std::thread)详解

    万次阅读 多人点赞 2021-07-17 19:40:26
    多线程?什么是多线程?进程与线程的区别C++11的std::threadstd::thread常用成员函数构造&析构函数常用成员函数举个栗子例一:thread的基本使用例二:thread执行有参数的函数例三:thread执行带有引用参数的函数...
  • 例子中多数命令都做了详细注释,包括常量也尽量进行了解释,自行参看吧。 源码看点: 1,扩展线程的正常退出方式。 2,指派线程CPU核心。 3,定时信息框的运用。 4,获取系统CPU核心数。 5,自动推荐使用线程数量。 ...
  • Java8——三种多线程方式

    千次阅读 2021-02-12 11:08:07
    1、多线程的使用方式1.1、继承Thread类继承Thread并重写run()方法,Thread类中的start方法会去调用系统的方法执行相应的线程。实际上Thread也是实现了Runable接口的,从该类的文档中我们能找到。1.2、实现Runable...
  • 多线程共享一块内存区域,但是对这块共享区域加锁访问。对调用static变量的方法使用lock或synchronized 《深入理解java虚拟机》知识点 程序运行的时候,内存主要由以下部分组成: 堆: 所有线程共享一...
  • 众所周知,多线程会造成线程安全问题,那么多线程为什么会导致线程安全问题呢? 一:首先了解jvm内存的运行时数据区 1.堆区:存储对象实例(和实例变量),数组等 2.java虚拟机栈(方法·栈),存放方法声明,...
  • 浅析多线程访问同一资源的问题

    千次阅读 2021-11-30 17:09:29
    线程在对同一个资源进行访问时要上锁 synchronized加在静态方法上和在代码中sychronized这个类是等价的: 加在非静态方法上和在代码中sychronized(this)是等价的 synchronized static void m() == sychronized ...
  • 易语言大漠多线程创建线程

    千次阅读 2020-05-30 09:22:19
    进程(process)和线程(thread)是操作系统的基本概念 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一...同一个进程中的线程之间可以并发执行 第一课易语言大
  • 这里写目录标题并发编程基础blocked 和 waiting 的区别线程的 run()和 start()有什么区别?为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用 run() 方法?说说线程的生命周期及五种基本状态...
  • JAVA之多线程

    万次阅读 2022-03-06 17:55:11
    一个进程可以由线程组成,即在一个进程中可以同时运行个不同的线程,它们分别执行不同的任务。 当进程内的线程同时运行,这种运行方式称为并发运行。 线程的运行机制 每个线程都有一个独立的程序计数器和...
  • Java多线程(超详细!)

    万次阅读 多人点赞 2021-05-12 17:00:59
    注意:一个进程可以启动线程。 eg.对于java程序来说,当在DOS命令窗口中输入: java HelloWorld 回车之后。 会先启动JVM,而JVM就是一个进程。 JVM再启动一个主线程调用main方法。 同时再启动一个垃圾回收线程...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 243,209
精华内容 97,283
关键字:

多线程常量

友情链接: crc16.rar