package org.simpleframework.xml.transform;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
import junit.framework.TestCase;
public class DateFormatterTest extends TestCase {
private static final String FORMAT = "yyyy-MM-dd HH:mm:ss.S z";
private static final int CONCURRENCY = 10;
private static final int COUNT = 100;
public void testFormatter() throws Exception {
DateFormatter formatter = new DateFormatter(FORMAT);
Date date = new Date();
String value = formatter.write(date);
Date copy = formatter.read(value);
assertEquals(date, copy);
}
public void testPerformance() throws Exception {
CountDownLatch simpleDateFormatGate = new CountDownLatch(CONCURRENCY);
CountDownLatch simpleDateFormatFinisher = new CountDownLatch(CONCURRENCY);
AtomicLong simpleDateFormatCount = new AtomicLong();
for(int i = 0; i < CONCURRENCY; i++) {
new Thread(new SimpleDateFormatTask(simpleDateFormatFinisher, simpleDateFormatGate, simpleDateFormatCount, FORMAT)).start();
}
simpleDateFormatFinisher.await();
CountDownLatch synchronizedGate = new CountDownLatch(CONCURRENCY);
CountDownLatch synchronizedFinisher = new CountDownLatch(CONCURRENCY);
AtomicLong synchronizedCount = new AtomicLong();
SimpleDateFormat format = new SimpleDateFormat(FORMAT);
for(int i = 0; i < CONCURRENCY; i++) {
new Thread(new SynchronizedTask(synchronizedFinisher, synchronizedGate, synchronizedCount, format)).start();
}
synchronizedFinisher.await();
CountDownLatch formatterGate = new CountDownLatch(CONCURRENCY);
CountDownLatch formatterFinisher = new CountDownLatch(CONCURRENCY);
AtomicLong formatterCount = new AtomicLong();
DateFormatter formatter = new DateFormatter(FORMAT, CONCURRENCY);
for(int i = 0; i < CONCURRENCY; i++) {
new Thread(new FormatterTask(formatterFinisher, formatterGate, formatterCount, formatter)).start();
}
formatterFinisher.await();
System.err.printf("pool: %s, new: %s, synchronized: %s", formatterCount.get(), simpleDateFormatCount.get(), synchronizedCount.get());
//assertTrue(formatterCount.get() < simpleDateFormatCount.get());
//assertTrue(formatterCount.get() < synchronizedCount.get()); // Synchronized is faster?
}
private class FormatterTask implements Runnable {
private DateFormatter formatter;
private CountDownLatch gate;
private CountDownLatch main;
private AtomicLong count;
public FormatterTask(CountDownLatch main, CountDownLatch gate, AtomicLong count, DateFormatter formatter) {
this.formatter = formatter;
this.count = count;
this.gate = gate;
this.main = main;
}
public void run() {
long start = System.currentTimeMillis();
try {
gate.countDown();
gate.await();
Date date = new Date();
for(int i = 0; i < COUNT; i++) {
String value = formatter.write(date);
Date copy = formatter.read(value);
assertEquals(date, copy);
}
}catch(Exception e) {
assertTrue(false);
} finally {
count.getAndAdd(System.currentTimeMillis() - start);
main.countDown();
}
}
}
private class SimpleDateFormatTask implements Runnable {
private CountDownLatch gate;
private CountDownLatch main;
private AtomicLong count;
private String format;
public SimpleDateFormatTask(CountDownLatch main, CountDownLatch gate, AtomicLong count, String format) {
this.format = format;
this.count = count;
this.gate = gate;
this.main = main;
}
public void run() {
long start = System.currentTimeMillis();
try {
gate.countDown();
gate.await();
Date date = new Date();
for(int i = 0; i < COUNT; i++) {
String value = new SimpleDateFormat(format).format(date);
Date copy = new SimpleDateFormat(format).parse(value);
assertEquals(date, copy);
}
}catch(Exception e) {
assertTrue(false);
} finally {
count.getAndAdd(System.currentTimeMillis() - start);
main.countDown();
}
}
}
private class SynchronizedTask implements Runnable {
private SimpleDateFormat format;
private CountDownLatch gate;
private CountDownLatch main;
private AtomicLong count;
public SynchronizedTask(CountDownLatch main, CountDownLatch gate, AtomicLong count, SimpleDateFormat format) {
this.format = format;
this.count = count;
this.gate = gate;
this.main = main;
}
public void run() {
long start = System.currentTimeMillis();
try {
gate.countDown();
gate.await();
Date date = new Date();
for(int i = 0; i < COUNT; i++) {
synchronized(format) {
String value = format.format(date);
Date copy = format.parse(value);
assertEquals(date, copy);
}
}
}catch(Exception e) {
assertTrue(false);
} finally {
count.getAndAdd(System.currentTimeMillis() - start);
main.countDown();
}
}
}
}