unsafe
1.反射创建Unsafe对象
@Test
public void test_createUnsafeObj ( ) throws NoSuchFieldException , IllegalAccessException {
final Field theUnsafe = Unsafe . class . getDeclaredField ( "theUnsafe" ) ;
theUnsafe. setAccessible ( true ) ;
Unsafe unsafe = ( Unsafe ) theUnsafe. get ( null ) ;
System . out. println ( unsafe) ;
}
2. Unsafe的CAS操作
@Test
public void test_UnsafeCas ( ) {
try {
Field theUnsafe = Unsafe . class . getDeclaredField ( "theUnsafe" ) ;
theUnsafe. setAccessible ( true ) ;
Unsafe unsafe = ( Unsafe ) theUnsafe. get ( null ) ;
long idOffset = unsafe. objectFieldOffset ( Student . class . getDeclaredField ( "id" ) ) ;
long nameOffset = unsafe. objectFieldOffset ( Student . class . getDeclaredField ( "name" ) ) ;
Student student = new Student ( ) ;
System . out. println ( student) ;
unsafe. compareAndSwapInt ( student, idOffset, 0 , 1 ) ;
unsafe. compareAndSwapObject ( student, nameOffset, null , "张三" ) ;
System . out. println ( student) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
class Student {
private volatile int id;
private volatile String name;
@Override
public String toString ( ) {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}' ;
}
}
3.自己实现原子整数类
package com. concurrent. p7 ;
import lombok. extern. slf4j. Slf4j ;
import org. junit. Test ;
import sun. misc. Unsafe ;
import java. lang. reflect. Field ;
import java. util. ArrayList ;
import java. util. List ;
@Slf4j ( topic = "c.Test_MyAtomicInteger" )
public class Test_MyAtomicInteger {
@Test
public void test_MyAtomicInteger ( ) {
MyAccount myAccount = new MyAccount ( 100000 ) ;
List < Thread > threadList = new ArrayList < > ( ) ;
for ( int i = 0 ; i < 10 ; i++ ) {
threadList. add ( new Thread ( ( ) -> {
for ( int j = 0 ; j < 10 ; j++ ) {
myAccount. decrement ( 1000 ) ;
}
} ) ) ;
}
threadList. forEach ( t -> t. start ( ) ) ;
threadList. forEach ( t -> {
try {
t. join ( ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
} ) ;
log. debug ( "余额:{}" , myAccount. getBalance ( ) ) ;
}
}
class MyAtomicInteger {
private volatile int value;
private static long valueOffset;
private static Unsafe unsafe;
static {
try {
Field theUnsafe = Unsafe . class . getDeclaredField ( "theUnsafe" ) ;
theUnsafe. setAccessible ( true ) ;
unsafe = ( Unsafe ) theUnsafe. get ( null ) ;
valueOffset = unsafe. objectFieldOffset ( MyAtomicInteger . class . getDeclaredField ( "value" ) ) ;
} catch ( NoSuchFieldException e) {
e. printStackTrace ( ) ;
} catch ( IllegalAccessException e) {
e. printStackTrace ( ) ;
}
}
public MyAtomicInteger ( int value) {
this . value = value;
}
public int getValue ( ) {
return value;
}
public boolean decrement ( int v) {
int prev, next;
do {
prev = getValue ( ) ;
next = prev - v;
} while ( ! unsafe. compareAndSwapInt ( this , valueOffset, prev, next) ) ;
return true ;
}
}
class MyAccount {
private MyAtomicInteger balance;
public MyAccount ( int balance) {
this . balance = new MyAtomicInteger ( balance) ;
}
public void decrement ( int value) {
balance. decrement ( value) ;
}
public int getBalance ( ) {
return balance. getValue ( ) ;
}
}