概述
Unsafe 对象提供了非常底层的,操作内存、线程的方法:CAS、LockSupport中的park、unpark
注意:unsafe实例无法通过getUnsafe()获取,只能通过反射获得。直接调用这个方法会抛出一个SecurityException异常,这是因为Unsafe仅供java内部类使用,外部类不应该使用它。
安全实现
class CasInt{
//CAS的底层实现:Unsafe
private static Unsafe unsafe;
//存放整数值的变量
private volatile int value;
//unsafe对象进行比较并交换的方法需要传入的第二个参数:被修改字段在内存中相对于被修改对象的偏移量
private static long valueOffset;
static {
try {
//反射获取unsafe对象
// 注意:unsafe实例无法通过getUnsafe()获取,只能通过反射获得。直接调用这个方法会抛出一个SecurityException异常,这是因为Unsafe仅供java内部类使用,外部类不应该使用它。
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
unsafe = (Unsafe) theUnsafe.get(null);
//获取偏移量
valueOffset = unsafe.objectFieldOffset(CasInt.class.getDeclaredField("value"));
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
CasInt(int value){
this.value=value;
}
//获取值
public int getValue(){
return value;
}
//减法
public boolean subtract(int value){
while (true){
if (unsafe.compareAndSwapInt(this, valueOffset, this.value, this.value-value)){
break;
}
}
return true;
}
//加法
public boolean increase(int value){
while (true){
if (unsafe.compareAndSwapInt(this, valueOffset, this.value, this.value+value)){
break;
}
}
return true;
}
}
不安全实现
class UnsafeInt{
//存放整数值的变量
private int data;
UnsafeInt(int value){
data=value;
}
//获取值
public int getValue(){
return data;
}
//减法
public boolean subtract(int value){
data=data-value;
return true;
}
//加法
public boolean increase(int value){
data=data+value;
return true;
}
}
测试与输出
测试代码
/**
* 分别定义两种值为10 0000 的整数。分别开启4个线程,每个线程对其进行2 5000 次减 1 的运算。
*/
public static void main(String[] args) throws InterruptedException {
// 1.分别定义两种值为10 0000 的整数
CasInt casInt=new CasInt(100000);
UnsafeInt unsafeInt=new UnsafeInt(100000);
List<Thread> list=new ArrayList<>();
// 2.分别创建4个线程,每个线程对其进行2 5000 次减 1 的运算
for (int i = 0; i < 4; i++) {
list.add(new Thread(()->{
for (int j = 0; j < 25000; j++) {
casInt.subtract(1);
}
}));
}
for (int i = 0; i < 4; i++) {
list.add(new Thread(()->{
for (int j = 0; j < 25000; j++) {
unsafeInt.subtract(1);
}
}));
}
// 3.启动线程
list.forEach(t->{
t.start();
});
// 4.主线程等待所有线程执行完毕
list.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 5.输出结果
log.debug("原子整数类的值为(安全):"+casInt.getValue());
log.debug("非原子整数类的值为(不安全):"+unsafeInt.getValue());
}
测试输出
16:43:00 [main] c.six-Demo2 - 原子整数类的值为(安全):0
16:43:00 [main] c.six-Demo2 - 非原子整数类的值为(不安全):56843