java中一个计数器如果超过MAX_VALUE再自增会如何?很可能会是负数。下面是一个安全的自增类
/* * Copyright 1999-2011 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.dubbo.common.utils; import java.util.concurrent.atomic.AtomicInteger; /** * AtomicPositiveInteger * * @author william.liangf * @author ding.lid */ public class AtomicPositiveInteger extends Number { private static final long serialVersionUID = -3038533876489105940L; private final AtomicInteger i; public AtomicPositiveInteger() { i = new AtomicInteger(); } public AtomicPositiveInteger(int initialValue) { i = new AtomicInteger(initialValue); } public final int getAndIncrement() { for (;;) { int current = i.get(); int next = (current >= Integer.MAX_VALUE ? 0 : current + 1); if (i.compareAndSet(current, next)) { return current; } } } public final int getAndDecrement() { for (;;) { int current = i.get(); int next = (current <= 0 ? Integer.MAX_VALUE : current - 1); if (i.compareAndSet(current, next)) { return current; } } } public final int incrementAndGet() { for (;;) { int current = i.get(); int next = (current >= Integer.MAX_VALUE ? 0 : current + 1); if (i.compareAndSet(current, next)) { return next; } } } public final int decrementAndGet() { for (;;) { int current = i.get(); int next = (current <= 0 ? Integer.MAX_VALUE : current - 1); if (i.compareAndSet(current, next)) { return next; } } } public final int get() { return i.get(); } public final void set(int newValue) { if (newValue < 0) { throw new IllegalArgumentException("new value " + newValue + " < 0"); } i.set(newValue); } public final int getAndSet(int newValue) { if (newValue < 0) { throw new IllegalArgumentException("new value " + newValue + " < 0"); } return i.getAndSet(newValue); } public final int getAndAdd(int delta) { if (delta < 0) { throw new IllegalArgumentException("delta " + delta + " < 0"); } for (;;) { int current = i.get(); int next = (current >= Integer.MAX_VALUE - delta + 1 ? delta - 1 : current + delta); if (i.compareAndSet(current, next)) { return current; } } } public final int addAndGet(int delta) { if (delta < 0) { throw new IllegalArgumentException("delta " + delta + " < 0"); } for (;;) { int current = i.get(); int next = (current >= Integer.MAX_VALUE - delta + 1 ? delta - 1 : current + delta); if (i.compareAndSet(current, next)) { return next; } } } public final boolean compareAndSet(int expect, int update) { if (update < 0) { throw new IllegalArgumentException("update value " + update + " < 0"); } return i.compareAndSet(expect, update); } public final boolean weakCompareAndSet(int expect, int update) { if (update < 0) { throw new IllegalArgumentException("update value " + update + " < 0"); } return i.weakCompareAndSet(expect, update); } public byte byteValue() { return i.byteValue(); } public short shortValue() { return i.shortValue(); } public int intValue() { return i.intValue(); } public long longValue() { return i.longValue(); } public float floatValue() { return i.floatValue(); } public double doubleValue() { return i.doubleValue(); } public String toString() { return i.toString(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((i == null) ? 0 : i.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; AtomicPositiveInteger other = (AtomicPositiveInteger) obj; if (i == null) { if (other.i != null) return false; } else if (!i.equals(other.i)) return false; return true; } }
相关推荐
1. **原子类**:Java的`AtomicLong`类是线程安全的,可以用于实现自增ID。每次获取新ID时,只需要调用`incrementAndGet()`方法,该方法会原子性地增加当前值并返回新的值。 2. **数据库序列**:如果使用的是支持...
本篇文章将详细介绍如何创建一个基于自增ID的唯一编号类,并通过算法说明和实例演示来阐述其工作原理。 首先,我们要明确目标:创建一个PHP类,它接受自增ID、自定义前缀和位数作为参数,然后生成一个唯一的编号。...
1. **类型安全**:确保自增运算符只对能够合理增加的类型进行操作。 2. **副作用**:前缀自增有副作用,而后缀自增有两次副作用(一次返回旧值,一次执行自增)。 3. **复合操作**:自增运算符重载要考虑与其他...
4. **TableIdentityVo.java**:这个文件名可能表示“表身份值对象”,它是封装ID生成相关数据的类,可能包含当前ID、步长、工作节点信息等字段,并提供相应的操作方法。 在实际应用中,自增ID生成器需要考虑性能、...
总结一下,通过PHP和Redis结合,我们可以构建一个可靠的计数器系统,适用于记录网站访问量、用户点击次数等需要并发安全自增的场景。Redis的原子性操作保证了数据的一致性,而PHP作为后端语言,可以方便地进行业务...
`AtomicInteger`是Java提供的原子整型类,它内部通过循环CAS(Compare and Swap)操作来实现线程安全的自增操作,而不需要显式地加锁解锁。 **示例代码**: ```java AtomicInteger count = new AtomicInteger(); count...
7. Java特点:Java具有安全性、分布性和移植性,但它是一种解释和编译混合的语言,不是编译执行。选项D(编译执行)是不正确的。 8. 类的定义和使用:Java程序的基本元素是类,每个类都有一个对应的源代码文件,...
通过这种方式,可以在不内置自增ID功能的情况下,确保在并发环境下安全地生成唯一的自增ID。不过,这种方法需要额外的存储空间和处理步骤,对于大规模并发写入的情况,可能需要评估性能影响。在设计数据库架构时,应...
6. **性能优化**:如果博主有涉及,可能会讨论如何优化时间类的性能,例如避免不必要的对象创建,或者利用线程安全的策略来处理并发场景下的时间操作。 7. **最佳实践**:可能还会分享一些在处理日期时间问题上的...
在Java中,实现雪花算法通常会创建一个Snowflake类,其中包含一个线程安全的序列号生成器和当前时间戳的存储。每次需要生成ID时,首先获取当前时间戳与上一次生成ID时的时间戳进行比较,如果时间戳未发生变化,则...
处理这类问题通常需要以下几个步骤: 1. **识别问题**:首先,需要确定表的当前最大id值,通过SQL查询`SELECT MAX(id) FROM tb1`来获取。 2. **创建影子表**:创建一个新的表tb2,其结构与tb1相同。使用`CREATE ...
C语言允许在一个表达式中使用多个赋值类运算符,包括赋值运算符、自增运算符和自减运算符等。这种灵活性让程序看起来简洁,但同时也可能引起副作用。 副作用的存在,会使程序变得难以理解,并容易产生误解或错误。...
而`donkeyid`通过算法优化,避免了这个问题,它可以在多台服务器上安全地生成不重复的ID,支持水平扩展。 `donkeyid`的实现可能包括以下几个关键点: 1. **分布式一致性**:`donkeyid`可能采用了类似于Twitter的...
1. **避免复杂参数**:在宏定义中,应避免使用自增、自减、函数调用等复杂操作,因为它们可能导致预处理器的意外行为。 2. **避免依赖计算顺序的表达式**:依赖计算顺序的表达式在不同编译器或优化级别下可能有不同...
7. **工具类的设计**:在Java等编程语言中,订单号生成工具类通常会设计为线程安全,提供静态方法供调用,以确保在多线程环境下的正确性。同时,可以考虑提供配置项,允许用户自定义订单号的格式和生成策略。 8. **...
这里的`AtomicInteger`保证了在并发环境下的线程安全,`getAndIncrement()`方法会原子性地获取当前值并增加1。 其次,`FileUtil.java`可能是用来处理文件操作的辅助类,它可能包含读写文件、创建目录等方法。在本例...
为了允许外部代码修改和查看这些值,提供了公共的`change`和`print`方法,这就是封装,它增加了代码的安全性和可维护性。 3. 构造函数与析构函数: 在第(3)部分,`a`类的构造函数用`new`关键字动态分配了一个整型...
在Java编程中,当我们在MySQL数据库中执行插入操作并希望获取新插入记录的自增ID时,有多种方法可以实现这一需求。以下是三种常见的方法,适用于不同的场景。 **方法一:使用PreparedStatement的RETURN_GENERATED_...
总结来说,MySQL提供了灵活的表达式和函数来处理字段的自增自减操作,使得我们可以安全地更新计数器类字段,而不用担心数值溢出的问题。在编写这类SQL语句时,一定要考虑到字段的数据类型和可能的边界情况,以确保...
注解方式适用于单个实体类,全局配置适用于项目中大部分实体类的共性需求,而默认策略则是一个安全的后盾,保证了在未明确指定策略时的正常运行。理解并正确运用这些策略,可以优化数据库操作,提高系统的稳定性和可...