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); }