Skip to content

Instantly share code, notes, and snippets.

@the8472
Created January 1, 2013 10:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save the8472/4426366 to your computer and use it in GitHub Desktop.
Save the8472/4426366 to your computer and use it in GitHub Desktop.
volatile/non-volatile/unsafe read test
import java.lang.reflect.Field;
import java.security.SecureRandom;
import sun.misc.Unsafe;
public class Test2 {
static final Unsafe unsafe;
static final long offsetA;
static final long offsetB;
static {
Unsafe unsafeInit;
try {
@SuppressWarnings("unchecked")
Class<Unsafe> unsafeClass = (Class<Unsafe>) Class.forName("sun.misc.Unsafe");
Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
unsafeInit = (Unsafe) unsafeField.get(unsafeClass);
}
catch (Exception e) {
unsafeInit = null;
}
unsafe = unsafeInit;
Field a = null;
Field b = null;
try
{
a = Test2.class.getDeclaredField("var1a");
b = Test2.class.getDeclaredField("var1b");
} catch (NoSuchFieldException | SecurityException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
offsetA = unsafeInit.objectFieldOffset(a);
offsetB = unsafeInit.objectFieldOffset(b);
}
public Test2() {
// TODO Auto-generated constructor stub
}
static volatile long escapeHatch;
volatile long[] var1a = new long[40];
volatile long[] var1b = new long[40];
final long[] var2a = new long[40];
final long[] var2b = new long[40];
SecureRandom rand = new SecureRandom();
static final int iterations = 90000000;
void prep(long[] a, long[] b) {
for(int i = 0;i<a.length;i++)
{
a[i] = rand.nextLong();
b[i] = rand.nextLong();
}
}
void test1() {
long counter = 0;
for(int i=0;i<iterations;i++)
counter += var1a[0]+= var1b[13]++;
escapeHatch = counter;
}
void test2() {
long counter = 0;
for(int i=0;i<iterations;i++)
counter += var2a[0]+= var2b[13]++;
escapeHatch = counter;
}
void test3() {
long counter = 0;
for(int i=0;i<iterations;i++)
counter += ((long[])unsafe.getObject(this, offsetA))[0]+= ((long[])unsafe.getObject(this, offsetB))[13]++;
escapeHatch = counter;
}
public static void main(String[] args) throws InterruptedException {
final Test2 t = new Test2();
Runnable runner1 = new Runnable() {
@Override
public void run() {
for(int i=0;i<10;i++)
{
t.prep(t.var1a, t.var1b);
long time = System.currentTimeMillis();
t.test1();
System.out.println("t1 " + (System.currentTimeMillis() - time));
}
}
};
Runnable runner2 = new Runnable() {
@Override
public void run() {
for(int i=0;i<10;i++)
{
t.prep(t.var2a, t.var2b);
long time = System.currentTimeMillis();
t.test2();
System.out.println("t2 " + (System.currentTimeMillis() - time));
}
}
};
Runnable runner3 = new Runnable() {
@Override
public void run() {
for(int i=0;i<10;i++)
{
t.prep(t.var1a, t.var1b);
long time = System.currentTimeMillis();
t.test3();
System.out.println("t3 " + (System.currentTimeMillis() - time)); }
}
};
Thread t1a = new Thread(runner1);
Thread t1b = new Thread(runner1);
Thread t2a = new Thread(runner2);
Thread t2b = new Thread(runner2);
Thread t3a = new Thread(runner3);
Thread t3b = new Thread(runner3);
t1a.start();
//t1b.start();
t1a.join();
t2a.start();
//t2b.start();
t2a.join();
t3a.start();
//t3b.start();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment