`

java 自增操作是原子操作

 
阅读更多

今天看了java并发编程实战,了解到java中基本类型的自增操作是非线程安全的,例如:

@NotThreadSafe
public class UnsafeSequence {
     private int value;
/** Returns a unique value. */
     public int getNext() {
     return value++;
}
}

 value的自增操作分为三个部分,先读后写两个操作,这两个操作不是原子的,是线程非安全的。

测试类如下:

package com.liuyao.java;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class UnSafeSequence implements Runnable{
	private int value = 0;

	private int getNext() {

		return value;
	}

	public static void main(String[] args) {

		UnSafeSequence us = new UnSafeSequence();
		ExecutorService exec = Executors.newCachedThreadPool();
		for(int i=0;i<100;i++) {
			exec.submit(us);
		}
		exec.shutdown();
		
		while(!exec.isTerminated());
		System.out.println(us.getNext());
	}

	@Override
	public void run() {
		for(int i=0;i<100;i++) {
			value++;
		}
	}
}

 启动100个线程,每个线程执行100次自增操作。由于读取的过程中会出现两次重复读的情况,所以最后的执行和会小于10000

分享到:
评论

相关推荐

    java快速ID自增器

    1. **原子类**:Java的`AtomicLong`类是线程安全的,可以用于实现自增ID。每次获取新ID时,只需要调用`incrementAndGet()`方法,该方法会原子性地增加当前值并返回新的值。 2. **数据库序列**:如果使用的是支持...

    springboot分布式自增id_javaredis_源码

    2. **Redis作为分布式ID生成器**:Redis的原子操作(如`INCR`命令)使得它可以安全地生成自增ID,多个客户端并发请求时也不会出现冲突。另外,通过设置键的过期时间,可以避免ID无限制增长。 3. **Redis的键过期...

    java多线程自增效率比较及原理解析

    在Java多线程环境中,自增操作是一种非常常见的需求。然而,由于多线程环境中的并发执行特性,简单的自增操作可能会导致数据不一致等问题。因此,在进行自增操作时必须考虑线程安全性。本文将详细介绍在多线程环境下...

    订单号的生成redis中获取

    例如,可以结合当前时间毫秒数、随机数和业务ID(如用户ID)生成一个长整型数值,然后通过Redis的原子递增操作将其转化为唯一的订单号。 总之,这个系统设计利用了Redis的高效性能,确保在高并发环境下也能快速生成...

    并发编程——原子操作CAS.pdf

    本文档详细介绍了并发编程中的原子操作,特别是Java语言中通过CAS(Compare-And-Swap)实现的原子操作,并指出了在实际编程中如何使用和实现原子操作。 首先,文档开篇就介绍了原子操作的定义。所谓原子操作,指的...

    Java16个原子类介绍-基于JDK8.docx

    原子类的核心在于它们提供的原子操作方法,例如`compareAndSet()`、`getAndSet()`、`getAndIncrement()`等。以`AtomicInteger`的`getAndIncrement()`为例,这个方法在不发生数据竞争的情况下,可以确保自增操作的...

    Java并发三大性质.docx

    Java内存模型(JMM)定义了8种原子操作:lock(锁定)、unlock(解锁)、read(读取)、load(载入)、use(使用)、assign(赋值)、store(存储)和write(操作)。这些操作用于保证不同线程间的数据同步和一致性...

    JAVA生成订单号(日期+流水号)

    如果是基于内存管理,如上述的`AtomicInteger`,则自增操作会自动保证递增性。同时,结合日期,订单号的全局唯一性也能得到保障。 5. **优化与扩展**:实际应用中,订单号可能还需要包含其他信息,如商家ID、渠道ID...

    java里的volatile关键字详解

    (a 非long 和double类型)这个操作是不可分割的,那么我们说这个操作时原子操作。 3. 有序性:Java语言提供了volatile 和synchronized 两个关键字来保证线程之间操作的有序性,volatile 是因为其本身包含“禁止指令重...

    java代码-volatile原子性

    为了确保原子性,Java提供了一些内置的原子类,如`AtomicInteger`,它们内部使用了`volatile`和CAS(Compare And Swap)操作来实现无锁并发。使用`AtomicInteger`进行自增操作,如`atomicCounter.incrementAndGet()`...

    原子类测试

    - `AtomicInteger`:提供了整型值的原子操作,如`incrementAndGet()`(自增)和`decrementAndGet()`(自减)。 - `AtomicLong`:与`AtomicInteger`类似,但用于长整型值。 - `AtomicBoolean`:用于布尔值的原子...

    Java并发编程(17)深入Java内存模型-内存操作规则

    但volatile不能保证原子性,例如,自增操作在多线程环境下可能会出现问题。 2. **synchronized关键字**:synchronized 提供了更强大的内存可见性和原子性保证。它保证了在同一时刻,只有一个线程可以执行某个同步...

    3、并发编程之CAS&amp;Atomic原子操作详解.pdf

    在计算机科学领域,原子操作是指一系列的操作被视为一个整体,在执行过程中不会被其他进程或线程打断的操作。简而言之,它确保了一系列操作要么全部完成,要么完全不执行。这一特性在并发编程中尤为重要,因为它能够...

    Java--CAS操作分析.txt_python怎么分析txt

    3. **只能保证一个共享变量的原子性**:CAS操作适用于单个共享变量的原子更新,对于多个共享变量的原子操作则需要更复杂的解决方案。 ### AtomicXXX类 为了克服`volatile`和CAS的限制,Java提供了`AtomicXXX`类,...

    Java获取最后插入MySQL记录的自增ID值的3种方法

    在Java编程中,当我们在MySQL数据库中执行插入操作并希望获取新插入记录的自增ID时,有多种方法可以实现这一需求。以下是三种常见的方法,适用于不同的场景。 **方法一:使用PreparedStatement的RETURN_GENERATED_...

    生成以日期开头,加4位数字,每次加1的工具类.如:201712140001

    其次,`FileUtil.java`可能是用来处理文件操作的辅助类,它可能包含读写文件、创建目录等方法。在本例中,虽然没有直接关联到生成序列号的功能,但可能会被用来将这些序列号保存到文件或者从文件中读取历史序列号,...

    java生成流水-格式202001270001

    这些类提供了线程安全的原子操作,避免了多线程环境下的同步问题。 - 在程序启动时,计数器初始化为1。每次需要生成新的流水号时,调用`incrementAndGet()`方法,它会自动增加1并返回新的值。 3. **多线程安全**:...

    CAS学习手册-JAVA程序员必备

    CAS机制是JAVA程序员处理并发问题的一种重要工具,它提供了无锁的原子操作,但在某些场景下,可能需要结合其他同步策略如`synchronized`或`Lock`来应对复杂的并发控制需求。理解并熟练应用CAS,可以提升多线程程序...

Global site tag (gtag.js) - Google Analytics