「java原子long」JAVA原子性操作与事务

博主:adminadmin 2022-12-14 05:03:06 73

本篇文章给大家谈谈java原子long,以及JAVA原子性操作与事务对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

Java中的Long和Double类型

Java中的原子操作包括:

1)除long和double之外的基本类型的赋值操作

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;

}

}

Java中如何实现原子操作

Java中的原子操作包括:

1)除long和double之外的基本类型的赋值操作

2)所有引用reference的赋值操作

3)java.concurrent.Atomic.* 包中所有类的一切操作

count++不是原子操作,是3个原子操作组合

1.读取主存中的count值,赋值给一个局部成员变量tmp

2.tmp+1

3.将tmp赋值给count

可能会出现线程1运行到第2步的时候,tmp值为1;这时CPU调度切换到线程2执行完毕,count值为1;切换到线程1,继续执行第3步,count被赋值为1------------结果就是两个线程执行完毕,count的值只加了1;

还有一点要注意,如果使用AtomicInteger.set(AtomicInteger.get() + 1),会和上述情况一样有并发问题,要使用AtomicInteger.getAndIncrement()才可以避免并发问题

为什么Java中的long与double不是线程安全的

您好,Java虚拟机规范定义的许多规则中的一条:所有对基本类型的操作,除了某些对long类型和double类型的操作之外,都是原子级的。

目前的JVM(java虚拟机)都是将32位作为原子操作,并非64位。当线程把主存中的 long/double类型的值读到线程内存中时,可能是两次32位值的写操作,显而易见,如果几个线程同时操作,那么就可能会出现高低2个32位值出错的情况发生。

要在线程间共享long与double字段是,必须在synchronized中操作,或是声明为volatile。

关于java原子long和JAVA原子性操作与事务的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

The End

发布于:2022-12-14,除非注明,否则均为首码项目网原创文章,转载请注明出处。