Сегодня наткнулся на эту публикацию, но хотел поделиться своими результатами (Пожалуйста, не комментируйте код, так как мне пришлось вручную вводить следующие классы, так как система, на которой я работал, не была подключена к Интернету:)
В итоге вывод кода ниже был следующим:
Результаты ATOMIC: истек = 25257 мс, ожидаемое значение = 50000, конечное значение = 50000, верно
Предварительные результаты: истек = 25257 мс, ожидаемое значение = 50000, конечное значение = 48991, ложь
Для моего использования в моем конкретном приложении я решил использовать атомарные значения для номеров статуса в классе мониторинга. На случай, если кто-то еще захочет просмотреть какие-то трудные результаты, я решил опубликовать эту информацию.
Хорошего дня!
Классы:
Я создал основной класс с примитивным long и атомарным long и методами приращения accessor, IncrementAtomicRunnable и IncrementPrimitiveRunnable.
LongOverhead:
public class LongOverhead{
AtomicLong atomicLong;
long primitiveLong;
public LongOverhead(){
atomicLong = new AtomicLong(0l);
primitiveLong = 0l;
}
public void incrAtomicLong(){
atomicLong.getAndAdd(1l);
}
public long getAtomicLong(){
return atomicLong.get();
}
public void incrPrimitiveLong(){
primitiveLong++;
}
public long getPrimitiveLong(){
return primitiveLong;
}
public static void main(String [] args){
String template = "%s Results: Elapsed = %d ms, ExpectedValue = %d, FinalValue = %d, %b";
int loopTotal = 1000;
int waitMilliseconds = 25;
int totalThreads = 50;
int expectedValue = loopTotal * totalThreads;
int whileSleep = 250;
LongOverhead atomic = new LongOverhead();
LongOverhead primitive = new LongOverhead();
List<Thread> atomicThreads = new ArrayList<>();
List<Thread> primitiveThreads = new ArrayList<>();
for(int x=0;x<totalThreads;x++){
Thread a = new Thread(new IncrementalAtomicRunnable(atomic, loopTotal, waitMilliseconds), "AtomicIncr" + x);
atomicThreads.add(a);
Thread p = new Thread(new IncrementalPrimitiveRunnable(primitive, loopTotal, waitMilliseconds), "PrimitiveIncr" + x);
primitiveThreads.add(p);
}
boolean cont = true;
long atomicStart = System.currentTimeMillis();
for(Thread t: atomicThreads){
t.start();
}
while(cont){
try{
Thread.sleep(whileSleep);
}catch(InterruptedException e){
e.printStackTrace();
}
boolean foundAlive = false;
for(Thread t: atomicThreads){
foundAlive = (State.TERMINATED != t.getState());
if(foundAlive){
break;
}
}
cont = foundAlive;
}
long atomicFinish = System.currentTimeMillis();
long atomicElapsed = atomicFinish - atomicStart;
long atomicFinal = atomic.getAtomicLong();
cont = true;
long primitiveStart = System.currentTimeMillis();
for(Thread t: primitiveThreads){
t.start();
}
while(cont){
try{
Thread.sleep(whileSleep);
}catch(InterruptedException e){
e.printStackTrace();
}
boolean foundAlive = false;
for(Thread t: primitiveThreads){
foundAlive = (State.TERMINATED != t.getState());
if(foundAlive){
break;
}
}
cont = foundAlive;
long primitiveFinish = System.currentTimeMillis();
long primitiveElapsed = primitiveFinish - primitiveStart;
long primitiveFinal = primitive.getPrimitiveLong();
System.out.println(String.format(template, "ATOMIC", atomicElapsed, expectedValue, atomicFinal, (expectedValue==atomicFinal)));
System.out.println(String.format(template, "PrImItIvE", primitiveElapsed, expectedValue, primitiveFinal, (expectedValue==primitiveFinal)));
}
IncrementAtomicRunnable:
public class IncrementAtomicRunnable implements Runnable{
protected LongOverhead oh;
protected int loopTotal;
protected int waitMilliseconds;
protected String currentThreadName;
public IncrementAtomicRunnable(LongOverhead oh, int loopTotal, int waitMilliseconds){
this.oh = oh;
this.loopTotal = loopTotal;
this.waitMilliseconds = waitMilliseconds;
}
@Override
public void run(){
currentThreadName = Thread.currentThread().getName();
System.out.println(currentThreadName + " for ATOMIC is starting.....");
for(int x=0;x<loopTotal;x++){
oh.incrAtomicLong();
try{
Thread.sleep(waitMilliseconds);
}catch(InterruptedException e){
System.out.println("InterruptedThread[" + currentThreadName + "], eating exception @@@@@");
}
}
System.out.println("....." + currentThreadName + " for ATOMIC is finished.");
}
}
и наконец
IncrementPrimitiveRunnable:
public class IncrementPrimitiveRunnable extends IncrementAtomicRunnable{
public IncrmentPrimitiveRunnable(LongOverhead oh, int loopTotal, int waitMilliseconds){
super(oh, loopTotal, waitMilliseconds);
}
@Override
public void run(){
super.currentThreadName = Thread.currentThread().getName();
System.out.println(currentThreadName + " for PRIMITIVE is starting.....");
for(int x=0;x<loopTotal;x++){
oh.incrPrimitiveLong();
try{
Thread.sleep(waitMilliseconds);
}catch(InterruptedException e){
System.out.println("InterruptedThread[" + currentThreadName + "], eating exception @@@@@");
}
}
System.out.println("....." + currentThreadName + " for PRIMITIVE is finished.");
}
}