Unsafe
通过反射获取Unsafe
public class UnsafeInstance {
public static Unsafe reflectGetUnsafe() {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
return (Unsafe) field.get(null);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("反射获取Unsafe失败");
}
}
}
分配直接内存
Unsafe unsafe = UnsafeInstance.reflectGetUnsafe();
long oneHundred = Long.MAX_VALUE;
long size = 1;
/*
* 调用allocateMemory分配内存
*/
long memoryAddress = unsafe.allocateMemory(size);
/*
* 将1写入到内存中
*/
unsafe.putAddress(memoryAddress, oneHundred);
/*
* 内存中读取数据
*/
long readValue = unsafe.getAddress(memoryAddress);
System.out.println("value : " + readValue);
读写屏障
UnsafeInstance.reflectGetUnsafe().loadFence();//读屏障
UnsafeInstance.reflectGetUnsafe().storeFence();//写屏障
UnsafeInstance.reflectGetUnsafe().fullFence();//读写屏障
锁
Unsafe unsafe = UnsafeInstance.reflectGetUnsafe();
unsafe.monitorEnter(object);
//业务逻辑写在此处之间
unsafe.monitorExit(object);
Atomic
AtomicInteger
public class AtomicIntegerTest {
public static AtomicInteger ATOMIC_INTEGER = new AtomicInteger(0);
public static volatile int number = 0;
public static void main(String[] args) throws InterruptedException {
List<Thread> list1 = new ArrayList<>(10);
List<Thread> list2 = new ArrayList<>(10);
for (int i = 0; i < 10; i++) {
Thread t = new Thread(() -> {
for (int j = 0; j < 10000; j++) {
ATOMIC_INTEGER.incrementAndGet();
}
}, "Thread-" + i);
list1.add(t);
}
for (int i = 0; i < 10; i++) {
Thread t = new Thread(() -> {
for (int j = 0; j < 10000; j++) {
number++;
}
}, "Thread-" + i);
list2.add(t);
}
list1.forEach(Thread::start);
list2.forEach(Thread::start);
TimeUnit.SECONDS.sleep(1);
System.out.println(ATOMIC_INTEGER.get());
System.out.println(number);
}
}
AtomicIntegerArray
public class AtomicIntegerArrayTest {
private static int[] ARR = {1,2};
private static AtomicIntegerArray ATOMIC_ARRAY = new AtomicIntegerArray(ARR);
public static void main(String[] args) {
ATOMIC_ARRAY.set(0,3);
System.out.println(ATOMIC_ARRAY.get(0));
System.out.println(ARR[0]);
}
}
AtomicReference
public class AtomicReferenceTest {
private static AtomicReference<User> atomicReference = new AtomicReference<>(new User());
private static AtomicInteger count = new AtomicInteger();
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 100; i++) {
int finalI = i;
new Thread(() -> {
User user = atomicReference.get();
wait(finalI*100000);//等待一会,模拟并发
User user1 = new User();
if (atomicReference.compareAndSet(user, user1)) {
count.incrementAndGet();
}
}).start();
}
TimeUnit.SECONDS.sleep(1);
System.out.println("修改成功次数:" + count.get());
}
public static void wait(final int time) {
for (int i = 0; i < time; i++) {
}
}
}
AtomicIntegerFieldUpdater
public class AtomicIntegerFieldUpdateTest {
static AtomicIntegerFieldUpdater<User> atomicIntegerFieldUpdater = AtomicIntegerFieldUpdater.newUpdater(User.class, "age");
static AtomicReferenceFieldUpdater<User, String> atomicReferenceFieldUpdater = AtomicReferenceFieldUpdater.newUpdater(User.class, String.class, "username");
public static void main(String[] args) {
User user = new User();
atomicIntegerFieldUpdater.set(user,18);
atomicReferenceFieldUpdater.set(user,"lzj");
System.out.println(atomicIntegerFieldUpdater.get(user));
System.out.println(atomicReferenceFieldUpdater.get(user));
}
}
ABA问题
public class AtomicABAProblem {
private static AtomicInteger atomicInteger = new AtomicInteger(10);
public static void main(String[] args) {
Thread owner = new Thread(() -> {
int money = atomicInteger.get();
System.out.println("第一次查看金库,金额:" + money);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("准备更新金库金额");
if(atomicInteger.compareAndSet(money, 20))
System.out.println("更新金库成功,金库剩余金额:"+atomicInteger.get());
else
System.err.println("更新失败,有人动了我的金库!");
});
Thread stealer = new Thread(() -> {
int money = atomicInteger.addAndGet(-3);
System.out.println("准备偷取金库,金库剩余金额" + money);
//使用金额做点别的事,比如炒一波股
money = atomicInteger.addAndGet(3);
System.out.println("将金额还回金库,金库剩余金额" + money);
});
owner.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
stealer.start();
}
}
ABA问题解决
public class SolveABAProblem {
static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(10, 0);
public static void main(String[] args) {
Thread owner = new Thread(() -> {
int money = atomicStampedReference.getReference();
int stamp = atomicStampedReference.getStamp();
System.out.println("第一次查看金库,金额:" + money + ",版本号:" + stamp);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("准备更新金库金额");
if (atomicStampedReference.compareAndSet(money, 20, stamp, stamp + 1))
System.out.println("更新金库成功,金库剩余金额:" + atomicStampedReference.getReference() + " 版本号:" + atomicStampedReference.getStamp());
else
System.err.println("更新失败,有人动了我的金库!");
});
Thread stealer = new Thread(() -> {
int[] stamp = new int[1];
int current = atomicStampedReference.get(stamp);
int remain = 7;
boolean success = atomicStampedReference.compareAndSet(current, remain, stamp[0], stamp[0] + 1);
if(success){
System.out.println("准备偷取金库,金库剩余金额" + remain);
//使用金额做点别的事,比如炒一波股
success = atomicStampedReference.compareAndSet(remain, current, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1);
if(success){
System.out.println("将金额还回金库,金库剩余金额" + atomicStampedReference.getReference());
}else {
System.err.println("完了,还回失败了");
}
}else {
System.err.println("偷取失败了");
}
});
owner.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
stealer.start();
}
}
自定义原子类
public class MyAtomicInteger {
private static final Unsafe unsafe = UnsafeInstance.reflectGetUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
private volatile int value;
public MyAtomicInteger(int initialValue) {
value = initialValue;
}
public int get() {
return value;
}
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
public static void main(String[] args) {
MyAtomicInteger myAtomicInteger = new MyAtomicInteger(10);
int i = myAtomicInteger.get();
int update = i + 1;
boolean b = myAtomicInteger.compareAndSet(i, update);
System.out.println(b);
System.out.println(myAtomicInteger.get());
}
}