java实现mysql递增流水号

先看为什么要实现这个递增的流水号

首先,让我们明确一下什么是流水号。通常,流水号是一个整数或字符串,用于标识一系列实体或记录。流水号的特点是每次使用都应该比上一次使用的+1,以此实现递增的效果。在多个并发连接的情况下,我们需要保证每个连接都能获得唯一的流水号并且能正常按顺序存储。

在java中生成递增流水号

在Java中,我们可以使用原子类和同步机制来实现递增的流水号生成

AtomicInteger

一、什么是AtomicInteger

  1. AtomicInteger类是系统底层保护的int类型,通过对int类型的数据进行封装,提供执行方法的控制进行值的原子操作,但AtomicInteger ≠ Integer
  2. AtomicInteger是一个提供原子操作的Integer类,通过线程安全的方式操作加减。
  3. 从JAVA 1.5开始,AtomicInteger 属于java.util.concurrent.atomic 包下的一个类。

二、AtomicInteger使用场景

  1. AtomicInteger提供原子操作来进行Integer的使用,适合高并发情况下的使用。
  2. foreach作循环的时候需要对应参数进行自增或者自减操作。

三、AtomicInteger作用

分析普通Java的运算操作:

Java中的运算操作在多线程是线程不安全的。比如i++解析为i=i+1,Java程序会把算式分为3个操作,获取值,计算值,赋予值,i++这个操作不具备原子性,多线程并发共享变量时必然会出现问题。

原子性:指的就是一个操作是不可中断,即使有多个线程执行,一个操作开始也不会受其他线程影响,即可以理解为线程的最小执行单元,不可被分割。

一个线程计算出值后,还未重新给变量赋值,另一个线程来读取到这个值,就会造成线程不安全的问题,有时候需要通过加锁的方式去保证线程安全,但是加锁对性能会有很大的影响。

AtomicInteger的作用:就是让程序在不加锁的时候也能保障线程安全

AtomicInteger不是通过传统的加锁机制实现的。它是基于硬件支持的原子操作来实现的,具体来说,它是通过CAS(Compare and Swap)操作来确保原子性的。CAS是一种无锁机制,它包含三个操作数——内存位置(V)、预期原值(A)和更新值(B)。执行CAS操作时,会将内存位置V的值与预期原值A进行比较。如果相匹配,那么处理器会自动将该内存位置V的值更新为B。如果不匹配,处理器不做任何操作。无论哪种情况,它都会在CAS指令之前返回该位置的值。这一过程是原子的,也就是说在执行过程中不会被其他线程中断。因此,AtomicInteger的操作不需要加锁,也能保证线程安全。

使用AtomicInteger生成

  1. 创建AtomicInteger类
1
2
3
4
5
6
7
8
9
10
import java.util.concurrent.atomic.AtomicInteger;

public class OrderNumberGenerator {
private static final AtomicInteger sequence = new AtomicInteger(0);

public static String generate() {
int nextValue = sequence.incrementAndGet();
return String.format("ORD%08d", nextValue);
}
}

以上代码使用了AtomicInteger类来保存当前的流水号。每次调用generate方法时,我们使用

incrementAndGet方法获取下一个流水号,并使用String.format方法将其格式化为指定的订单号格式

  1. 使用AtomicInteger生成
1
2
3
4
5
6
7
8
9
10
11
public class Order {
private String orderNumber;

public Order() {
this.orderNumber = OrderNumberGenerator.generate();
}

public String getOrderNumber() {
return orderNumber;
}
}

在上面的代码中,我们在订单的构造方法中调用了流水号生成器的generate方法,并将生成的流水号赋值给订单实例的orderNumber属性。

现在,每当我们创建一个新的订单对象时,它将自动获得一个唯一的订单号。

AtomicInteger对原子操作的常用方法

addAndGet()- 以原子方式将给定值添加到当前值,并在添加后返回新值。

getAndAdd() - 以原子方式将给定值添加到当前值并返回旧值。

incrementAndGet()- 以原子方式将当前值递增1并在递增后返回新值。它相当于i ++操作。

getAndIncrement() - 以原子方式递增当前值并返回旧值。它相当于++ i 操作。

decrementAndGet()- 原子地将当前值减1并在减量后返回新值。它等同于i– 操作。

getAndDecrement() - 以原子方式递减当前值并返回旧值。它相当于– i 操作。