1.sun.misc.Unsafe 示例
package com.java.magic.part4.exception;
import java.lang.reflect.Field;
import sun.misc.Unsafe;
class Target{
int intParam = 3;
long longParam;
String strParam;
String strParam1;
}
public class UnsafeTest {
private static Unsafe unsafe;
static{
try {
//通过反射获取theUnsafe
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe)field.get(null);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
Class clazz = Target.class;
Field[] fields = clazz.getDeclaredFields();
System.out.println("fieldNameeeee:fieldOffset");
for(Field f : fields){
//获取属性偏移量,可以通过这个偏移量给属性设值
System.out.println(f.getName()+" : "+unsafe.objectFieldOffset(f));
}
System.out.println("--------------------------------");
Target target = new Target();
Field intParam = clazz.getDeclaredField("intParam");
int a = (Integer) intParam.get(target);
System.out.println("intParam原始值:"+a);
long intParamOffset = unsafe.objectFieldOffset(intParam);
System.out.println("intParam实例变量偏移量:"+intParamOffset);
//intParam实例变量偏移量是offset 原始值是3,我们要改成10
System.out.println(unsafe.compareAndSwapInt(target, intParamOffset, 3, 10));
System.out.println("intParam改变之后的值:"+target.intParam);
System.out.println("--------------------------------");
//这个时候已经改为10了,所以会返回false
System.out.println(unsafe.compareAndSwapInt(target, intParamOffset, 3, 10));
System.out.println("--------------------------------");
Field strParam = clazz.getDeclaredField("strParam");
String str = (String) strParam.get(target);
System.out.println("strParam原始值:"+str);
long strParamOffset = unsafe.objectFieldOffset(strParam);
System.out.println("strParam实例变量的偏移量是:"+strParamOffset);
System.out.println(unsafe.compareAndSwapObject(target, strParamOffset, null, "5"));
System.out.println("strParam改变之后的值:"+target.strParam);
}
}
2.java.util.concurrent.locks.Condition
package com.java.magic.part4.exception;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class NumberWrapper{
public int value = 1;
}
public class ConditionTest {
public static void main(String[] args) {
//初始化可重入锁
final Lock lock = new ReentrantLock();
//第一个条件当屏幕上输出到3
final Condition reachThreeCondition = lock.newCondition();
//第二个条件当屏幕上输出到6
final Condition reachSixCondition = lock.newCondition();
//NumberWrapper只是为了封装一个数字,一边可以将数字对象共享
final NumberWrapper num = new NumberWrapper();
//初始化A线程,这个线程输出123, 789
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
//reachThreeCondition.signal(); 这个东西需要放到lock.lock()和lock.unlock()之间使用
lock.lock();
try{
while(num.value <= 3){
System.out.println(Thread.currentThread().getName()+" : "+(num.value++));
}
reachThreeCondition.signal();//唤醒由reachThreeCondition.await()造成阻塞的线程
} finally{
lock.unlock();
}
lock.lock();
try {
if(num.value < 6){
reachSixCondition.await();//阻塞当前线程,直到reachSixCondition.signal()唤醒当前线程
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
lock.unlock();
}
while(num.value <= 9){
System.out.println(Thread.currentThread().getName()+" : "+(num.value++));
}
}
});
//初始化B线程,这个线程输出456
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
try{
if(num.value < 3){
reachThreeCondition.await();//阻塞当前线程,直到reachThreeCondition.signal()唤醒当前线程
}
} catch(Exception e){
} finally{
lock.unlock();
}
lock.lock();
try{
while(num.value <= 6){
System.out.println(Thread.currentThread().getName()+" : "+(num.value++));
}
reachSixCondition.signal();//唤醒由reachSixCondition.await()造成阻塞的线程
} finally{
lock.unlock();
}
}
});
//
threadA.start();
threadB.start();
}
}
3.求以2为低N的对数
方法1(推荐)
public static int log2(int i)
{
int r = 0;
while ((i >>= 1) != 0)
{
++r;
}
return r;
}
方法2
Math.log(N)/Math.log(2)
4.获取long类型的数组中首个元素的偏移量和每个元素的所占内存空间大小
public static void unsafeTest() throws Exception{
Unsafe unsafe = getUnsafe();
//获取long类型的数组中首个元素的偏移量
int offset = unsafe.arrayBaseOffset(long[].class);
//获取long类型的数组中为每个元素分配的内存空间大小
int scale = unsafe.arrayIndexScale(long[].class);
System.out.println("offset:"+offset+", scale:"+scale);
long[] buffer = new long[10];
//unsafe
unsafe.putOrderedLong(buffer, offset+ 16, 1003l);
System.out.println(buffer[2]);
}
5.AtomicReferenceFieldUpdater类
package com.java.magic.part4.exception;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import sun.misc.Unsafe;
public class Test {
protected volatile String[] names = new String[0];
/**
* 参考:http://huangyunbin.iteye.com/blog/1944153
* AtomicReferenceFieldUpdater<AbstractSequencer, Sequence[]> SEQUENCE_UPDATER =
AtomicReferenceFieldUpdater.newUpdater(AbstractSequencer.class, Sequence[].class, "gatingSequences");
*/
public static void AtomicReferenceFieldUpdaterTest() throws Exception{
AtomicReferenceFieldUpdater<Test, String[]> updater = AtomicReferenceFieldUpdater.newUpdater(Test.class, String[].class, "names");
Test test = new Test();
System.out.println(test.names);
System.out.println(updater.get(test)); //获取对象里面的成员变量,说明获取的是Test中的names
}
}
6.Arrays.copyOf() 方法
public static void arraysCopyOf(){
String[] names = {"高伟刚","高红成","高显兵"};
System.out.println("names length:"+names.length);
String[] newnames = Arrays.copyOf(names, 5);
System.out.println("newnames length:"+newnames.length);
for(int i =0 ; i< newnames.length; i++){
System.out.println(newnames[i]);
}
}
7.jdk5新特性:可变参数
/*
* 如果传的是数组的话,那么names的长度是数据的大小
*/
public static void paramTest(String... names){
System.out.println(names.length);
}