https://www.myziyuan.com/
- 金牛科技
- Java中的原子操作包括:1)除long和double之外的基本类型的1981赋值操作2)所有引用reference的赋值操作3)java.concurrent.Atomic.* 包中所有类的一切操作。但是java对long和double的赋值操作是非原子操作!!long和double占用的字节数都是8,也就是64bits。在32位操作系统上对64位的数据的读写要分两步完成,每一步取32位数据。这样对double和long的赋值操作就会有问题:如果有两个线程同时写一个变量内存,一个进程写低32位,而另一个写高32位,这样将导致获取的64位数据是失效的数据。因此需要使用volatile关键字来防止此类现象。volatile本身不保证获取和设置操作的原子性,仅仅保持修改的可见性。但是java的内存模型保证声明为volatile的long和double变量的get和set操作是原子的。(from )举个例子来说:(example is from )public class UnatomicLong implements Runnable { private static long test = 0;private final long val;public UnatomicLong(long val) { this.val = val; }@Override public void run() { while (!Thread.interrupted()) { test = val; //两个线程都试图将自己的私有变量val赋值给类私有静态变量test } }public static void main(String[] args) { Thread t1 = new Thread(new UnatomicLong(-1)); Thread t2 = new Thread(new UnatomicLong(0));System.out.println(Long.toBinaryString(-1)); System.out.println(pad(Long.toBinaryString(0), 64));t1.start(); t2.start();long val; while ((val = test) == -1 || val == 0) { //如果静态成员test的值是-1或0,说明两个线程操作没有交叉 }System.out.println(pad(Long.toBinaryString(val), 64)); System.out.println(val);t1.interrupt(); t2.interrupt(); }// prepend 0s to the string to make it the target length private static String pad(String s, int targetLength) { int n = targetLength - s.length(); for (int x = 0; x < n; x++) { s = "0" + s; } return s; }}
- 2021-11-28 23:32:13
- 11212121
- C / C ++标准中的长整数(长)和长双倍精度类型(长双倍)的特定大小未指定,只是说:char \u003c\u003d short \u003c\u003d int \u003c\u003d long \u003c\u003d long longfloat \u003c\u003d double\u003c\u003d long double并指定其中一些允许的值。在32位机器编译器我们通常使用,例如VC和GCC,长型为32位,尺寸相同,尺寸相同;long long(__int64)是64位。和旧的东西tc,int是16,长的是32位,没有lon long。浮点是真的,并且Vc中的长双倍使用80位,而且GCC仅为64位,与Double相同。因此,这些类型对不同的机器以及不同的编译器具有不同的影响。特定使用必须引用您使用的帮助文档,或者查看限制中相关宏的大小float.h,如何使用它。
- 2021-11-28 23:30:59
- LouisWang
- c++long double怎么用,#include <stdio.h>#include <stdlib.h>int main(){long double a;scanf("%lf",&a);printf("a=%lf",a);system("pause>nul");return 0;}
- 2021-11-28 23:30:59