Performance test:singleton class with and without double check locking - performance

I have two implementations of singleton classes
public class Test2 {
private static Test2 _instance=new Test2();
private Test2(){
}
public static synchronized Test2 getInstance(){
if(_instance == null){
_instance = new Test2();
}
return _instance;
}
}
And:
public class TestSingleton {
private static TestSingleton _instance=new TestSingleton();
private TestSingleton(){
}
public static TestSingleton getInstance(){
if (_instance == null) {
synchronized (TestSingleton.class) {
if (_instance == null) {
_instance = new TestSingleton();
}
}
}
return _instance;
}
I want to parametrize my finding in terms of time taken, what I did is this:
Callable<Long> task = new Callable<Long>() {
#Override
public Long call() throws Exception {
long start = System.nanoTime();
**TestSingleton.getInstance();**
long end = System.nanoTime();
return end - start;
}
};
for (int i = 0; i < 100000; i++) {
futList.add(es1.submit(task));
}
for (Future<Long> fut : futList) {
try {
totalTime1.getAndAdd(fut.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Time taken by S1 " + totalTime1.get());
.
.
ExecutorService es2 = Executors.newFixedThreadPool(threadpool);
Callable<Long> task1 = new Callable<Long>() {
#Override
public Long call() throws Exception {
long start = System.nanoTime();
Test2.getInstance();
long end = System.nanoTime();
return end - start;
}
};
for (int i = 0; i < 100000; i++) {
futList1.add(es2.submit(task1));
}
for (Future<Long> fut : futList1) {
try {
totalTime2.getAndAdd(fut.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Time taken by S2 " + totalTime2.get());
The results I got is:
Time taken by S1 4636498
Time taken by S2 5127865
First question is this the correct approach? and second even if I comment the getinstances method in both the call(), I get different times of execution of two identical blocks:
Time taken by S1 1506640
Time taken by S2 2156172

Don't measure each execution and sum the times, there will be too much inaccuracy in the individual measurements. Instead, get start time, execute 100000 times, get end time. Also, execute a few 1000 times before you start measuring to avoid skewing by start-up costs.

Related

Spring Boot Return the Response Before the Process is Complete

I am using Spring Boot to process certificate and client postman to interact with service, assumption privatekey, publickey and certificate has been process decrypted, then using CertificateHelper getCertificate() function to parseX509Certificate
private List<Certificate> getCA(X509Certificate cert, Date tsp) {
Security.addProvider(new BouncyCastleProvider());
try {
String cnIssuer = X500Name.asX500Name(cert.getIssuerX500Principal()).getCommonName();
int xTry = 0;
while ((resultCA == null || resultCA_C5 == null || resultCA_C3 == null || resultCA_v1 == null) && xTry <= 3) {
LOGGER.info(LogSystem.getLog("TRY :" + xTry, tsp, "LOG"));
try {
loadCAinit();
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchProviderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
xTry++;
}
if (xTry > 3) {
return null;
}
for (int i = 0; i < 4; i++) {
List<Certificate> CACheck;
if (i == 0) {
CACheck = resultCA;
} else if (i == 1) {
CACheck = resultCA_C3;
} else if (i == 2) {
CACheck = resultCA_C5;
} else {
CACheck = resultCA_v1;
}
LOGGER.info(LogSystem.getLog("CA CHECK : " + CACheck.get(0).toString(), tsp, "LOG"));
X509Certificate certCA;
try {
LogSystem.info("Process getcertificate on certificate helper");
certCA = (X509Certificate) CertificateHelper.getCertificate(CACheck.get(0).getCertificateData());
LogSystem.info("End process getcertificate on certificate helper");
String cnIssuerCheck = X500Name.asX500Name(certCA.getSubjectX500Principal()).getCommonName();
System.out.println(" CA CN: " + cnIssuerCheck);
System.out.println("User Issuer CN: " + cnIssuer);
if (cnIssuer.equals(cnIssuerCheck)) {
LOGGER.info(LogSystem.getLog("DN CA:" + certCA.getSubjectDN().toString() + ", SN: " + certCA.getSerialNumber().toString(16).toUpperCase(), tsp, "LOG"));
LOGGER.info(LogSystem.getLog("DN User:" + cert.getSubjectDN().toString() + ", SN: " + cert.getSerialNumber().toString(16).toUpperCase(), tsp, "LOG"));
return CACheck;
}
} catch (CertificateException e) {
// TODO Auto-generated catch block
LOGGER.info(LogSystem.getLog(" CATCH 1", tsp,"LOG"));
e.getCause();
e.printStackTrace();
System.out.println("asas");
}
}
LOGGER.info(LogSystem.getLog("Issuer " + cnIssuer + " not found : " + cert.getIssuerDN(), tsp, "LOG"));
System.out.println("asas");
} catch (IOException e) {
// TODO Auto-generated catch block
LOGGER.info(LogSystem.getLog(" CATCH 2", tsp,"LOG"));
e.printStackTrace();
System.out.println("asas");
}
LOGGER.info(LogSystem.getLog(" RETURN NULL", tsp,"LOG"));
System.out.println("asas");
return null;
}
getCertificate() function on class CertificateHelper
package org.ejbca.core.protocol.ws.common;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import org.cesecore.util.Base64;
import org.cesecore.util.CertTools;
public class CertificateHelper {
public static final String RESPONSETYPE_CERTIFICATE = "CERTIFICATE";
public static final String RESPONSETYPE_PKCS7 = "PKCS7";
public static final String RESPONSETYPE_PKCS7WITHCHAIN = "PKCS7WITHCHAIN";
public static final int CERT_REQ_TYPE_PKCS10 = 0;
public static final int CERT_REQ_TYPE_CRMF = 1;
public static final int CERT_REQ_TYPE_SPKAC = 2;
public static final int CERT_REQ_TYPE_PUBLICKEY = 3;
public CertificateHelper() {
}
public static Certificate getCertificate(byte[] certificateData) throws CertificateException {
Certificate retval = CertTools.getCertfromByteArray(Base64.decode(certificateData), Certificate.class);
return retval;
}
public static byte[] getPKCS7(byte[] pkcs7Data) {
return Base64.decode(pkcs7Data);
}
}
on getCertificate() function call another class CertTools function getCertfromByteArray()
public static <T extends Certificate> T getCertfromByteArray(byte[] cert, Class<T> returnType) throws CertificateParsingException {
return getCertfromByteArray(cert, "BC", returnType);
}
and detail function of getCertfromByteArray()
public static <T extends Certificate> T getCertfromByteArray(byte[] cert, String provider, Class<T> returnType) throws CertificateParsingException {
T ret = null;
String prov = provider;
if (provider == null) {
prov = "BC";
}
if (returnType.equals(X509Certificate.class)) {
ret = parseX509Certificate(prov, cert);
} else if (returnType.equals(CardVerifiableCertificate.class)) {
ret = parseCardVerifiableCertificate(prov, cert);
} else {
try {
ret = parseX509Certificate(prov, cert);
} catch (CertificateParsingException var8) {
try {
ret = parseCardVerifiableCertificate(prov, cert);
} catch (CertificateParsingException var7) {
throw new CertificateParsingException("No certificate could be parsed from byte array. See debug logs for details.");
}
}
}
return (Certificate)ret;
}
process on line 779 get log print
process on line 780 can't execution then client get returned response with http code 200
proses on line 781 not execution because on line 780
any suggestion why from line 780 give response to my postman with null body and http code success 200 ?
*Note class CertificateHelper and CertTools is library from official https://mvnrepository.com/artifact/org.ejbca

Get queue size of ThreadPoolTaskExecutor and add to queue in Spring boot

I have the following class which has multiple custom ThreadPoolTaskExecutors I am showing it with one in this example.
#Configuration
#EnableAsync
public class ExecutorConfig {
#Bean(name = "streetCheckerExecutor")
public Executor getStreetAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(50);
executor.setQueueCapacity(1000000);
executor.setThreadNamePrefix("streetCheckerExecutor-");
executor.initialize();
return executor;
}
}
I have the following class which gets content from the database, I want to be able to check the queue size of streetCheckerExecutor and if it's less than a certain number, to add the content to the queue
#Component
public class StreetChecker {
#Autowired
StreetRepository streetRepository;
#Autowired
StreetCheckService streetChecker;
#EventListener(ApplicationReadyEvent.class)
public void checkStreets() {
try {
List<Street> streetList = streetRepository.getStreets();
for (int i = 0; i < streetList.size(); i++) {
streetChecker.run(streetList.get(i));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("---------------------");
}
}
}
And below is the worker class
#Component
public class StreetCheckService {
#Async("streetCheckerExecutor")
public void run(Content content) {
try {
//do work
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}
I am working with a lot of data and I don't want to grab everything from the database every time, but I want to check the queue size of streetCheckerExecutor and if it's less than a number, I want to get more content from the database and add it to the streetCheckerExecutor queque
Below is how I'm thinking I can do it by converting the above checkStreets to the one below
#EventListener(ApplicationReadyEvent.class)
public void checkStreets() {
while (true) {
try {
// check the queue size of streetCheckerExecutor
// if less than a number
// add to the queue
// else keep waiting and will try again in X minutes
} catch (Exception e) {
} finally {
try {
Thread.sleep(1000 * 60);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
But how would I be able to get the size of the queue in the checkStreets() method?
You can just autowire in your ThreadPoolTaskExecutor and get the queue with getThreadPoolExecutor().getQueue().
#Autowire
#Qualifier("streetCheckerExecutor")
private Executor streetExecutor;
#EventListener(ApplicationReadyEvent.class)
public void checkStreets() {
while (true) {
try {
final BlockingQueue<Runnable> queue = streetExecutor.getThreadPoolExecutor().getQueue();
if(queue.size() <= 5) {
queue.add(() -> {
final List<Street> streetList = streetRepository.getStreets();
streetList.forEach(street -> {
streetChecker.run(street);
});
});
}
} catch (Exception e) {
} finally {
try {
Thread.sleep(1000 * 60);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
i'm not sure this is what you meant, but something like this maybe.

OrientDB client CPU goes over 100% with ODB2.2.20

I want to load lots of data into Orient DB with multiple threads.
I'm using OrientDB 2.2.20 and Java 1.8.0_131 to run below sample test client.
But when I run this client with 5 threads and 10000 samples then the client's CPU usage goes over 100% and the process becomes almost dead.
Actually I wanted to use graph APIs to create huge number of vertices and edges between them.
But I read in some post that for massive inserts use document API and set the in & out pointers using doc APIs. Hence tried this program.
Could someone point what is wrong in the code?
public OrientDBTestClient(){
db = new ODatabaseDocumentTx(url).open(userName, password);
}
public static void main(String[] args) throws Exception{
int threadCnt = Integer.parseInt(args[0]);
OrientDBTestClient client = new OrientDBTestClient();
try {
db.declareIntent(new OIntentMassiveInsert());
Thread[] threads = new Thread[threadCnt];
for (int i = 0; i < threadCnt; i++) {
Thread loadStatsThread = new Thread(client.new LoadTask(Integer.parseInt(args[1])));
loadStatsThread.setName("LoadTask" + (i + 1));
loadStatsThread.start();
threads[i] = loadStatsThread;
}
}
catch(Exception e){
e.printStackTrace();
}
}
private class LoadTask implements Runnable{
public int count = 0;
public LoadTask(int count){
this.count = count;
}
public void run(){
long start = System.currentTimeMillis();
try{
db.activateOnCurrentThread();
for(int i = 0; i < count; ++ i){
storeStatsInDB(i +"");
}
}
catch(Exception e){
log.println("Error in LoadTask : " + e.getMessage());
e.printStackTrace();
}
finally {
db.commit();
System.out.println(Thread.currentThread().getName() + " loaded: " + count + " services in: " + (System.currentTimeMillis() - start) + "ms");
}
}
}
public void storeStatsInDB(String id) throws Exception{
try{
long start = System.currentTimeMillis();
ODocument doc = db.newInstance();
doc.reset();
doc.setClassName("ServiceStatistics");
doc.field("serviceID", id);
doc.field("name", "Service=" + id);
doc.save();
}
catch(Exception e){
log.println("Exception :" + e.getMessage());
e.printStackTrace();
}
}
db instances aren't sharable between threads.
You have two choices:
create an instance for each thread
use the pool (my first choice): http://orientdb.com/docs/last/Java-Multi-Threading.html#working-with-databases
The following example is extracted from internal tests:
pool = new OPartitionedDatabasePool("remote:localshot/test", "admin", "admin");
Runnable acquirer = () -> {
ODatabaseDocumentTx db = pool.acquire();
try {
List<ODocument> res = db.query(new OSQLSynchQuery<>("SELECT * FROM OUser"));
} finally {
db.close();
}
};
//spawn 20 threads
List<CompletableFuture<Void>> futures = IntStream.range(0, 19).boxed().map(i -> CompletableFuture.runAsync(acquirer))
.collect(Collectors.toList());
futures.forEach(cf -> cf.join());`

Why different result each run?

I'm playing around with CompletableFuture and streams in Java 8 and I get different printouts each time I run this. Just curious, why?
public class DoIt {
public static class My {
private long cur = 0;
public long next() {
return cur++;
}
}
public static long add() {
long sum = 0;
for (long i=0; i<=100;i++) {
sum += i;
}
return sum;
}
public static long getResult(CompletableFuture<Long> f) {
long l = 0;
try {
f.complete(42l);
l = f.get();
System.out.println(l);
} catch (Exception e) {
//...
}
return l;
}
public static void main(String[] args){
ExecutorService exec = Executors.newFixedThreadPool(2);
My my = new My();
long sum = Stream.generate(my::next).limit(20000).
map(x -> CompletableFuture.supplyAsync(()-> add(), exec)).
mapToLong(f->getResult(f)).sum();
System.out.println(sum);
exec.shutdown();
}
}
If I skip the f.complete(42l) call I always get the same result.
http://download.java.net/jdk8/docs/api/java/util/concurrent/CompletableFuture.html#complete-T-
by the time the complete(42l) call happens, some add()'s may have already completed.

how to create a image slideshow for blackberry?

what i am trying to do is that on click of a button in screen1, i try push the screen2 repeatedly with different images and different Transition Context.
the code is as follows
public void fieldChanged(Field field, int context)
{
if(field==slideButton)
{
for(int i=0;i<bitmaps.length;i++)
{
slideScreen = new SliderScreen(bitmaps[i]);
UiApplication.getUiApplication().pushScreen(slideScreen);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
UiApplication.getUiApplication().popScreen(slideScreen);
}
}
}
}
Problem is that nothing appears.Is there any other way to achieve this..
Fixed version of your initial idea:
public void fieldChanged(Field field, int context) {
if (field==slideButton) {
final UiApplication app = UiApplication.getUiApplication();
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < bitmaps.length; i++) {
final SliderScreen slideScreen =
new SliderScreen(bitmaps[i]);
app.invokeAndWait(new Runnable() {
public void run() {
app.pushScreen(slideScreen);
}
});
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
app.invokeAndWait(new Runnable() {
public void run() {
app.popScreen(slideScreen);
}
});
}
}
}).start();
}
}
Your code did not work because the UI thread was sleeping between push and pop, so it has no time/chance to start drawing the screen. Note I moved the entire action into a separate thread. So now the main UI thread has free time to actually make drawing.

Resources