提交 cc01756c 编写于 作者: Z zhouwangwang

add README

上级 374bc7df
# 用Unsafe实现AtomicInteger类
**原理**
AtomicInteger可以在并发情况下达到原子化更新,避免使用了synchronized,而且性能非常高。
![在这里插入图片描述](https://img-blog.csdnimg.cn/img_convert/7fa0b413ccc4eebf79a7d3f4fa8ba5e6.png#pic_center)
AtomicInteger的底层是用Unsafe来实现的,这里我们手写一个AtomicInteger类,并且测试一下。
**测试例子**
启动 1000 个线程,每个线程做 -10 元 的操作,如果初始余额为 10000 那么正确的结果应当是 0。
以下代码在JDK1.8通过测试。
## 账户Account 类
```java
interface Account {
// 获取余额
Integer getBalance();
// 取款
void withdraw(Integer amount);
/**
* 方法内会启动 1000 个线程,每个线程做 -10 元 的操作
* 如果初始余额为 10000 那么正确的结果应当是 0
*/
static void demo(Account account) {
List<Thread> ts = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
ts.add(new Thread(() -> {
account.withdraw(10);
}));
}
long start = System.nanoTime();
ts.forEach(Thread::start);
ts.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
long end = System.nanoTime();
System.out.println(account.getBalance()
+ " cost: " + (end-start)/1000_000 + " ms");
}
}
```
## Account 实现类
```java
class DiyAccount implements Account {
private DiyAtomicInteger balance;
public DiyAccount(int balance) {
this.balance = new DiyAtomicInteger(balance);
}
@Override
public Integer getBalance() {
return balance.getValue();
}
@Override
public void withdraw(Integer amount) {
balance.decrement(amount);
}
}
```
## DiyAtomicInteger 类
```java
class DiyAtomicInteger {
private volatile int value; //实例操作的变量
private static final long valueOffset;//偏移量
private static final Unsafe UNSAFE;// unsafe实例对象
static {
UNSAFE = UnsafeAccessor.getUnsafe();
try {
valueOffset = UNSAFE.objectFieldOffset(DiyAtomicInteger.class.getDeclaredField("value"));
} catch (NoSuchFieldException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public int getValue() {
return value;
}
public void decrement(int amount) {
while (true) {
int prev = this.value;
int next = prev - amount;
if (UNSAFE.compareAndSwapInt(this, valueOffset, prev, next)) {
break;
}
}
}
public DiyAtomicInteger(int value) {
this.value = value;
}
}
```
## 测试
```java
public class Test {
public static void main(String[] args) {
Account account = new DiyAccount(10000);
Account.demo(account);
}
}
```
输出
```
0 cost: 65 ms
```
## 其它——Unsafe工具类UnsafeAccessor
我们知道`Unsafe `的构造方法是私有的,也没有`get`方法可以获取对象,所以我们只能通过反射的方式来实例化`Unsafe` 对象。
```java
public final class Unsafe {
private static final Unsafe theUnsafe;
private Unsafe() {
}
...
}
```
所以
```java
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class UnsafeAccessor {
private static final Unsafe unsafe;
static {
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
unsafe = (Unsafe) theUnsafe.get(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new Error(e);
}
}
public static Unsafe getUnsafe() {
return unsafe;
}
}
```
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册