import java.util.ArrayList;
interface ICounter {
void inc();
void dec();
int get();
}
class Counter implements ICounter {
protected int counter = 0;
public void inc() { counter++; }
public void dec() { counter--; }
public int get() { return counter; }
}
class SynchronizedCounter extends Counter {
public synchronized void inc() { counter++; }
public synchronized void dec() { counter--; }
}
class BetterCounter implements ICounter {
protected long up = 0;
protected long down = 0;
public void inc() { up++; }
public void dec() { down--; }
public int get() { return (int)(up + down); }
}
class SynchronizedBetterCounter extends BetterCounter {
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc() { synchronized(lock1) { up++; } }
public void dec() { synchronized(lock2) { down--; } }
}
class Inc extends Thread {
ICounter i;
public Inc(ICounter i) { this.i = i; }
public void run() {
for(int x = 0; x < 2147483647 ; x++) {
i.inc();
}
}
}
class Dec extends Thread {
ICounter i;
public Dec(ICounter i) { this.i = i; }
public void run() {
for(int x = 0; x < 2147483647 ; x++) {
i.dec();
}
}
}
public class Main {
public static void main(String[] args) {
ICounter[] c = {new Counter(), new SynchronizedCounter(), new BetterCounter(), new SynchronizedBetterCounter()};
int numberOfCounters = 4;
ArrayList<Inc> inc = new ArrayList<>();
ArrayList<Dec> dec = new ArrayList<>();
for(int i = 0; i < numberOfCounters; i++) {
inc.add(new Inc(c[i]));
dec.add(new Dec(c[i]));
}
long start = 0;
long stop = 0;
int returnVal[] = new int[4];
long execTime[] = new long[4];
for(int i = 0; i < numberOfCounters; i++) {
start = System.currentTimeMillis();
inc.get(i).start();
dec.get(i).start();
try {
inc.get(i).join();
dec.get(i).join();
} catch (InterruptedException ex) {
}
stop = System.currentTimeMillis();
returnVal[i] = c[i].get();
execTime[i] = stop-start;
}
for(int i = 0; i < 4; i++) {
System.out.println("Counter: " + c[i].getClass().getSimpleName());
System.out.println("Value of counter: " + returnVal[i]);
System.out.println("Execution time: " + execTime[i] + " ms\n");
}
}
}
The goal is to make counter with methods inc
to increase value and dec
to decrease it. It's written in 4 ways - the basic, with synchronization, with 2 variables (1 to increase, 2 to decrease) and with 2 variables and synchronization. There are 2 classes Inc
and Dec
for multithreading.
I know there can be problems with this code, but the goal is just to add and subtract big number, just once, as fast as possible.
Output
Counter: Counter
Value of counter: 2061724420
Execution time: 141 ms
Counter: SynchronizedCounter
Value of counter: 0
Execution time: 174210 ms
Counter: BetterCounter
Value of counter: 0
Execution time: 39468 ms
Counter: SynchronizedBetterCounter
Value of counter: 0
Execution time: 52176 ms
Question: Why first execution time is so small, comparing to the others?