package com.cin.test;
import java.rmi.RemoteException;
import java.util.*;
import javax.naming.NamingException;
import com.cin.dto.GenericRequest;
import com.cin.dto.UserDTO;
import com.cin.ejb.controllerejb.*;
import com.cin.exceptions.InvalidInputValueException;
import com.cin.exceptions.MissingInformationException;
import com.cin.exceptions.MissingInputValueException;
import com.cin.jndi.lookup.*;
public class DeadlockTest {
ControllerRemote controller;
//int ssn = 10;
//int ssn = 102205128;
//int ssn = 102202986;
int ssn = 102200154;
static int clientCounter = 1;
public DeadlockTest() throws RemoteException, NamingException{
EJBLookup lookup = EJBLookup.getInstance();
controller = lookup.getControllerEJB();
}
public void deadlockOnScoreCache() {
List<Thread> clients = new ArrayList<Thread>();
clients.add(new Thread(new Client(ClientJob.GET_SCORE)));
clients.add(new Thread(new Client(ClientJob.UPDATE)));
for (Thread client : clients) {
client.start();
}
waitForClientToFinish(clients);
}
public void serializedOnScoreCache() throws MissingInputValueException{
tryUpdate();
tryGetScore();
tryUpdate();
}
private void tryUpdate(){
try {
UserDTO user = new UserDTO(ssn);
GenericRequest request = new GenericRequest();
request.setUser(user);
user = controller.retrieveUserDetails(request).getUser();
String newDetail = ""+new Random().nextInt();
user.setDetail(newDetail);
controller.updateUserRecord_test(user);
} catch (Exception e) {
e.printStackTrace();
}
}
private void tryGetScore() {
try {
ArrayList<UserDTO> users = new ArrayList<UserDTO>();
users.add(new UserDTO(ssn));
GenericRequest request = new GenericRequest();
request.setUserList(users);
controller.calculateScoreForUsers(request);
} catch (MissingInformationException e) {
e.printStackTrace();
} catch (InvalidInputValueException e) {
e.printStackTrace();
}
}
private void waitForClientToFinish(List<Thread> clients){
try{
int sleep = 200;
Thread.sleep(2000);
do{
List<Boolean> clientAlive = new ArrayList<Boolean>();
for( Thread c : clients){
clientAlive.add( c.isAlive() );
}
boolean someAlive = false;
for( Boolean alive : clientAlive){
if( alive ){
someAlive = true;
}
}
if( someAlive ){
for( int c = 0; c < clientAlive.size(); c++){
System.out.println("Client "+c+" alive="+clientAlive.get(c));
}
System.out.println();
Thread.sleep(sleep);
}else{
return;
}
}while(true);
}catch(InterruptedException ex){
System.out.println("Processing was interrupted.");
System.out.println("Client threads are still running and might never stop.");
}
}
public static void main(String args[]){
try{
DeadlockTest test = new DeadlockTest();
System.out.println("Trying serialized access.");
test.serializedOnScoreCache();
System.out.println("Concurrent access.");
test.deadlockOnScoreCache();
System.out.println("EXIT");
}catch(Exception ex){
System.err.println("Unexpected exception: ");
ex.printStackTrace();
}
}
public enum ClientJob{UPDATE, GET_SCORE};
private class Client implements Runnable{
private ClientJob job;
public Client(ClientJob newJob){
this.job = newJob;
clientCounter++;
}
public void run() {
switch(job){
case UPDATE:
tryUpdate();
break;
case GET_SCORE:
tryGetScore();
break;
default:
assert false;
break;
}
}
}// end of class Client
}