Java如何解决可见性和有序性的问题(java 可见性 volatile)

并发二 原子性 可见性 有序性

今天给各位分享Java如何解决可见性和有序性的问题的知识,其中也会对java问题解决办法进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录

  1. 如何解决'java'不是内部或外部命令的问题
  2. Java如何解决可见性和有序性的问题
  3. 请教java小问题
  4. java工程师面试,问你开发中遇到的最困难的问题是什么自己是怎么解决的怎么回答比较好呢

如何解决'java'不是内部或外部命令的问题

在我们使用cmd输入命令时,经常遇到不是内部或外部命令,也不是可运行的程序。这样的问题,但是我们的电脑上明明有这个软件。这个问题的原因是我们没有正确配置环境变量,那么应该怎么设置呢?

1.在我的电脑上点击右键,选择属性。

2.在系统面板里选择“高级界面设置”。

3.在系统属性界面的“高级”选项卡里,选择下方的“环境变量”。

4.接下来手动找一下我们电脑上安装完的java,然后找到bin路径,并且复制这个路径。

5.回到环境变量界面,选中上方的“path”,然后点击编辑按钮。

6.在“变量值”后方追加我们刚才复制的字符串,注意要与前面的字符串有一个“;”作为隔断。

7.点击确定之后,再次打开cmd输入java,就可以正常使用了。

Java如何解决可见性和有序性的问题

首先需要了解,为什么会有「可见性」和「时序性」问题,然后我们来看Java是如何解决这两个问题的。

「可见性」和「时序性」问题

导致「可见性」和「时序性」问题的原因有如下几个:

抢占式任务执行:现代CPU执行多任务方式是「抢占式」,它的总控制权在操作系统手中,操作系统会轮流给需要CPU执行的任务分配执行时间片,超过时间后,操作系统会剥夺当前任务的CPU使用权,把它排在队列的最后,最后分配时间片……

存储速度差异:各存储执行速度的不同,离CPU越近,存储速度越快,相对的容量就越小。执行程序所需要的数据不可能一次性全部都加载到寄存器中,所以有load与store的过程,影响了所谓的「可见性」

指令重排:大多数现代微处理器都会采用将指令乱序执行(out-of-orderexecution,简称OoOE或OOE)的方法,在条件允许的情况下,直接运行当前有能力立即执行的后续指令,避开获取下一条指令所需数据时造成的等待。通过乱序执行的技术,处理器可以大大提高执行效率。除了处理器,常见的Java运行时环境的JIT编译器也会做指令重排序操作,即生成的机器指令与字节码指令顺序不一致。

解决方法

解决思路很简单,就是把多线程强制单线程执行。

解决方法无非两种:

内存屏障

先看下JVM的内存模型,我们基于这个模型来简单说明下

内存屏障

内存屏障在Java中通过volatile关键字体现。volatile会在适当的地方添加下面四种内存屏障。

LoadLoad屏障:对于这样的语句Load1;LoadLoad;Load2,在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。

StoreStore屏障:对于这样的语句Store1;StoreStore;Store2,在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见。

LoadStore屏障:对于这样的语句Load1;LoadStore;Store2,在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕。

StoreLoad屏障:对于这样的语句Store1;StoreLoad;Load2,在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。它的开销是四种屏障中最大的。在大多数处理器的实现中,这个屏障是个万能屏障,兼具其它三种内存屏障的功能。

内存屏障只保证可见性,不保证时序性。也就是说内存屏障只是解决了线程A修改的内容能立刻被线程B读到。

Java中锁按性质分可以分悲观锁和乐观锁。悲观锁基于锁指令实现,乐观锁基于CAS实现。

通过monitorenter和monitorexit两个指令实现悲观锁,这两个指令之间的指令不得重排,且独占。假设线程A和线程B同时执行一段代码,线程A先通过monitorenter获取到了锁,那么在线程A执行monitorexit之前,线程B都只能等待。

CAS即CompareAndSet,Java通过自旋以及CPU层级的指令实现。具体可参考JUC实现。假设有一个变量c,初始值为3。线程A和线程B同时修改这个变量,A,B都同时获取到了变量c的值,A首先进行修改,将值改成了4。B尝试修改,但是发现c的值现在是4而不是3,所以进行自旋等待,然后重新执行修改操作,将4改成了5。

ThreadLocal

最后说下ThreadLocal。ThreadLocal即本地线程变量,也就是将公共的变量直接拿到线程内使用,其中的修改对外不影响。谈不上解决了「可见性」和「时序性」。只是保证了当前线程内的修改不影响其它线程,其它线程的修改也不影响当前线程。

请教java小问题

值为-2

一、先掌握一些理论知识

1.int的取值区间:

最大值为2147483647,最小值为-2147483648。

2.int溢出特性:

正数过大溢出为负数,负数过小溢出为正数,

即,最大值2147483647再增1得到-2147483648,

同理,最小值-2147483648再减1得到2147483647

3.整数直接量默认为int型:

如:1、2、99、56...,整数直接量默认都是int类型

4.不同数据类型之间做数学运算:

当不同数据类型的变量之间进行数学运算,最终结果取最大的那个数据类型,

如:double与long类型的变量做数学运算时,结果为double类型。

二、再来分析这道题

1.inti=Integer.MIN_VALUE;

//声明一个整型变量i,并赋值为int最小值,即i中存-2147483648;

2.i-1

//i为int型,1为整数直接量也是int型,结果仍为int,溢出为2147483647;

3.i-1L

//i为int型,1L为long型,运算后结果为long,不溢出,为-2147483649;

4.(i-1)+(i-1L)

//即,2147483647+(-2147483649),故结果为-2

我是苏max疯,想了解更多java培训、学习相关内容,记得点击关注我哦~

java工程师面试,问你开发中遇到的最困难的问题是什么自己是怎么解决的怎么回答比较好呢

结合实际经验,回答你遇到的问题,或者你熟悉的技术,说说你遇到什么问题,怎么调研,怎么解决的,主要是解决问题的思路

文章分享结束,Java如何解决可见性和有序性的问题和java问题解决办法的答案你都知道了吗?欢迎再次光临本站哦!

Java 100天知识进阶 Java内存 知识铺 四

声明:本文内容来自互联网不代表本站观点,转载请注明出处:https://bk.77788889.com/11/88291.html

相关推荐