How to give message when Threadpool Executor is completed? - java

I am trying to give a pop up alert message when my ThreadpoolExecutor is finished executing. It is searching email addresses from websites, once it is done I want a alert message as "Completed". Here is my Thread :-
public class Constant
{
public static final int NUM_OF_THREAD = 60;
public static final int TIME_OUT = 10000;
}
ThreadPoolExecutor poolMainExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool
(Constant.NUM_OF_THREAD);
Here is my Searching Operation class :-
class SearchingOperation implements Runnable {
URL urldata;
int i;
Set<String> emailAddresses;
int level;
SearchingOperation(URL urldata, int i, Set<String> emailAddresses, int level) {
this.urldata = urldata;
this.i = i;
this.emailAddresses = emailAddresses;
this.level = level;
if (level != 1)
model.setValueAt(urldata.getProtocol() + "://" + urldata.getHost() + "/contacts", i, 3);
}
public void run() {
BufferedReader bufferreader1 = null;
InputStreamReader emailReader = null;
System.out.println(this.i + ":" + poolMainExecutor.getActiveCount() + ":" + level + ";" + urldata.toString());
try {
if (level < 1) {
String httpPatternString = "https?:\\/\\/(www\\.)?[-a-zA-Z0-9#:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9#:%_\\+.~#?&//=]*)";
String httpString = "";
BufferedReader bufferreaderHTTP = null;
InputStreamReader httpReader = null;
try {
httpReader = new InputStreamReader(urldata.openStream());
bufferreaderHTTP = new BufferedReader(httpReader
);
StringBuilder rawhttp = new StringBuilder();
while ((httpString = bufferreaderHTTP.readLine()) != null) {
rawhttp.append(httpString);
}
if (rawhttp.toString().isEmpty()) {
return;
}
List<String> urls = getURL(rawhttp.toString());
for (String url : urls) {
String fullUrl = getMatchRegex(url, httpPatternString);
if (fullUrl.isEmpty()) {
if (!url.startsWith("/")) {
url = "/" + url;
}
String address = urldata.getProtocol() + "://" + urldata.getHost() + url;
fullUrl = getMatchRegex(address, httpPatternString);
}
if (!addressWorked.contains(fullUrl) && fullUrl.contains(urldata.getHost())) {
addressWorked.add(fullUrl);
sendToSearch(fullUrl);
}
}
} catch (Exception e) {
//System.out.println("652" + e.getMessage());
//e.printStackTrace();
return;
} finally {
try {
if (httpReader != null)
bufferreaderHTTP.close();
} catch (Exception e) {
// e.printStackTrace();
}
try {
if (httpReader != null)
httpReader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
String someString = "";
emailReader = new InputStreamReader(urldata.openStream());
bufferreader1 = new BufferedReader(
emailReader);
StringBuilder emailRaw = new StringBuilder();
while ((someString = bufferreader1.readLine()) != null) {
if (someString.contains("#")) {
emailRaw.append(someString).append(";");
}
}
//Set<String> emailAddresses = new HashSet<String>();
String emailAddress;
//Pattern pattern = Pattern
//.compile("\\b[a-zA-Z0-9.-]+#[a-zA-Z0-9.-]+\\.[a-zA-Z0-9.-]+\\b");
Pattern
pattern = Pattern
.compile("\\b[a-zA-Z0-9.-]+#[a-zA-Z0-9.-]+\\.[a-zA-Z0-9.-]+\\b");
Matcher matchs = pattern.matcher(emailRaw);
while (matchs.find()) {
emailAddress = (emailRaw.substring(matchs.start(),
matchs.end()));
// //System.out.println(emailAddress);
if (!emailAddresses.contains(emailAddress)) {
emailAddresses.add(emailAddress);
// //System.out.println(emailAddress);
if (!foundItem.get(i)) {
table.setValueAt("Found", i, 4);
foundItem.set(i, true);
}
String emails = !emailAddresses.isEmpty() ? emailAddresses.toString() : "";
model.setValueAt(emails, i, 2);
model.setValueAt("", i, 3);
}
}
} catch (Exception e) {
//System.out.println("687" + e.getMessage());
} finally {
try {
if (bufferreader1 != null)
bufferreader1.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
if (emailReader != null)
emailReader.close();
} catch (Exception e) {
e.printStackTrace();
}
Thread.currentThread().interrupt();
return;
}
}
After this the final snippet :-
private void sendToSearch(String address) throws Throwable {
SearchingOperation operation = new SearchingOperation(new URL(address), i,
emailAddresses, level + 1);
//operation.run();
try {
final Future handler = poolMainExecutor.submit(operation);
try {
handler.get(Constant.TIME_OUT, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
e.printStackTrace();
handler.cancel(false);
}
} catch (Exception e) {
//System.out.println("Time out for:" + address);
} catch (Error error) {
//System.out.println("Time out for:" + address);
} finally {
}
}

Implement Callable<Void> instead of Runnable and wait for all the task to terminate by calling Future<Void>.get():
class SearchingOperation implements Callable<Void>
{
public Void call() throws Exception
{
//same code as in run()
}
}
//submit and wait until the task complete
Future<Void> future = poolMainExecutor.submit(new SearchingOperation()).get();

Use ThreadPoolExecutor.awaitTermination():
Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.
As in your code, you create your ThreadPoolExecutor first
ThreadPoolExecutor poolMainExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(Constant.NUM_OF_THREAD);
Then, you need to add Tasks to it:
poolMainExecutor.execute(myTask);
poolMainExecutor.submit(myTask);
execute will return nothing, while submit will return a Future object. Tasks must implement Runnable or Callable. An object of SearchingOperation is a task for example. The thread pool will execute the tasks in parallel, but each task will be executed by one thread. That means to effectively use NUM_OF_THREAD Threads you need to add at least NUM_OF_THREAD Tasks.
(Optional) Once you got all jobs to work, shutdown your pool. This will prevent new tasks from being submitted. It won't affect running tasks.
poolMainExecutor.shutdown();
At the end, you need to wait for all Tasks to complete. The easiest way is by calling
poolMainExecutor.awaitTermination(Integer.MAX_VALUE, TimeUnit.DAYS);
You should adjust the amount of time you want to wait for the tasks to finish before throwing an exception.
Now that the work is done, notify the user. A simple way is to call one of the Dialog presets from JOptionPane, like:
JOptionPane.showMessageDialog(null, "message", "title", JOptionPane.INFORMATION_MESSAGE);
It will popup a little window with title "title", the message "message", an "information" icon and a button to close it.

This code can be used., it will check whether the execution is completed in every 2.5 seconds.
do {
System.out.println("In Progress");
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (poolMainExecutor.getActiveCount() != 0);
System.out.println("Completed");

Related

Semaphore does not invoke release()

I have implemented a thread in an Android app that is invoked every minute, the invocation of the process occur through an Alarm Manager.
#Override
public void onReceive(Context context, Intent intent) {
try {
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock;
if (powerManager != null) {
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Send-data");
wakeLock.acquire(10 * 60 * 1000L);
new Thread(new SendPolicyData(context)).start();
wakeLock.release();
}
} catch (Exception e) {
wil.WriteFile("1)AlarmSendData - Exception: " + e.toString());
}
}
The code contained in the thread extract a set of data from a database that must be sent through posts to a server, the access to resources is controlled via a semaphore.
#SuppressWarnings("ResultOfMethodCallIgnored")
public class SendPolicyData implements Runnable {
private static final WriteInLogFile wil = new WriteInLogFile();
private final Context ctx;
public SendPolicyData(Context ctx) {
this.ctx = ctx;
}
public void run() {
try {
SemaphoreDTS.getInstance().goIn();
Authentication singleCall = new Authentication();
Utilities utilities = new Utilities(ctx);
DbGest dbGest = DbGest.getInstance(ctx);
if (utilities.checkConnection()) {
int lastProcessedID = -1;
int attempts = 0;
Cursor cursor = dbGest.freeQuery("SELECT id, label, value, priority FROM " + TABLE_DATATOSEND + " ORDER BY priority,dateIns");
if (cursor != null) {
cursor.moveToFirst();
if (cursor.getCount() > 0) {
do {
int toProcessID = cursor.getInt(cursor.getColumnIndex("id"));
String value = cursor.getString(cursor.getColumnIndex("value"));
String labelString = cursor.getString(cursor.getColumnIndex("label"));
if (lastProcessedID == toProcessID) {
if (attempts <= 5) {
attempts++;
Thread.sleep(3000);
} else {
attempts = 0;
dbGest.changeDTSRecordPriority(toProcessID);
}
}
switch (labelString) {
case "photo":
//DO STUFF
break;
lastProcessedID = toProcessID;
} while (cursor.moveToNext());
}
cursor.close();
}
}
} catch (Exception e) {
SemaphoreDTS.getInstance().goOut();
wil.WriteFile("7)SendPolicyData - Exception: " + e.toString());
} finally {
SemaphoreDTS.getInstance().goOut();
}
SemaphoreDTS.getInstance().goOut();
}
}
This is the source code of the semaphore that I use to manage the access to the resources.
public class SemaphoreDTS {
private static SemaphoreDTS instance;
private final Semaphore semaphore;
private final WriteInLogFile wil = new WriteInLogFile();
private SemaphoreDTS() {
this.semaphore = new Semaphore(1, true);
}
public static SemaphoreDTS getInstance() {
if (instance == null) {
instance = new SemaphoreDTS();
}
return instance;
}
public synchronized void goIn() {
try {
semaphore.acquire();
} catch (Exception e) {
wil.WriteFile("1)SemaphoreDTS - Exception: " + e.toString());
}
}
public synchronized void goOut() {
try {
semaphore.release();
} catch (Exception e) {
wil.WriteFile("2)SemaphoreDTS - Exception: " + e.toString());
}
}
}
During the tests that I did, it often happens that the semaphore remains blocked, for some reason the necessary release is not invoked in order to be able to perform new acquire.
I think I have written the code correctly and I don't understand where I am wrong.
In this code's block:
catch (Exception e) {
SemaphoreDTS.getInstance().goOut();
wil.WriteFile("7)SendPolicyData - Exception: " + e.toString());
} finally {
SemaphoreDTS.getInstance().goOut();
}
SemaphoreDTS.getInstance().goOut();
You always have two calls .goOut(), because finally block always will invoke.
When you call .release() (in your method .goOut()) semaphore gets availible permit, i.e instead 1 permit your semaphore gets 2 permits. I think problem starts here. Try to delete calls `.goOut() method everywhere but not in finally()

Missing data in serial communication

IN serial communication some time data miss at receive time and some time its miss and send time at receiver side . I observe that data send and receive successfully when I am set baud rate is 300800 please check following code ===>
receiver==>
I am using Jserial com for communication
also open port port and set baud rate, partity=1, NumDataBits=8,NumStopBits=1
comPort.addDataListener(new SerialPortDataListener() {
#Override
public int getListeningEvents() {
{
return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
}
// return 0;
}
#Override
public void serialEvent(SerialPortEvent serialPortEvent) {
if (serialPortEvent.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
logger.info("in HLIToModbusConversionController" + "event_type="
+ serialPortEvent.getEventType());
return;
}else {
logger.info("in HLIToModbusConversionController getCommandFromSerial() getEventType:" + serialPortEvent.getEventType());
}
ExecutorService executorService = null;
try {
//50 ml time out
executorService = Executors.newSingleThreadExecutor();
long sTime = System.currentTimeMillis();
int len = serialPortEvent.getSerialPort().bytesAvailable();
byte dataBuffer[] = new byte[len];
serialPortEvent.getSerialPort().readBytes(dataBuffer, len);
for (int i = 0; i < dataBuffer.length; i++) {
byte b = dataBuffer[i];
logger.info("in HLIToModbusConversionController" + String.format("%02x ", b));
}
logger.info("in HLIToModbusConversionController" + dataBuffer);
Future<byte[]> future = executorService
.submit(new TimeOutTask(hliToModbusService, dataBuffer));
while (!future.isDone()) {
long totalTime = System.currentTimeMillis() - sTime;
if (totalTime > configurationModel.getModbusTimeout()) {
logger.info("Task is taking long time to execute so cancelling it..");
future.cancel(true);
}
}
byte responseFrame[] =null;
//byte responseFrame[] = hliToModbusService.decodeHLICommand(dataBuffer); // service
try {
responseFrame = future.get((long) configurationModel.getModbusTimeoutSecond(), TimeUnit.SECONDS);
logger.info("result:"+responseFrame);
fileOperationUtil.writeFramFromCache(responseFrame);
} catch (Exception e) {
logger.info("50 millisecond time out frame takes from cache");
responseFrame =fileOperationUtil.readFramFromCache();
} // call
modbusRequest.setTimeout(false);
if (responseFrame != null) {
comPort.writeBytes(responseFrame, responseFrame.length);
logger.info("in HLIToModbusConversionController response frame sent" + responseFrame);
// wait for 100ms
} else {
logger.info(
"in HLIToModbusConversionController responseFrame is empty" + responseFrame);
}
String finalFrame="";
for(byte data:responseFrame) {
finalFrame=finalFrame+","+data;
}
logger.info(
"in HLIToModbusConversionController final responseFrame:" + finalFrame);
startTimer();
logger.info("in HLIToModbusConversionController returns from startTimer");
} catch (Exception e) {
logger.info("in HLIToModbusConversionController exception occurs");
e.printStackTrace();
}finally{
if(executorService != null){
executorService.shutdown();
}
}}
});
}
}
//comPort = SerialPort.getCommPorts()[0]; // take 1st port
} catch (Exception e) {
logger.info("in HLIToModbusConversionController exception occurs");
e.printStackTrace();
}
logger.info("in HLIToModbusConversionController");
logger.info("Server started");
logger.info("Waiting for a client ...");
return "Hli server started";

Multiple ExecutorCompletionService not working

I've a requirement to start and stop task from java application. I'm trying to use
ExecutorService to create threads and ExecutorCompletionService to check
processing status of thread . Startup and stop is a continious activity so in my
test code I've created a while loop .
public class ProcessController {
String[] processArray = { "Process1", "Process2", "Process3", "Process4", "Process5", "Process6", "Process7" };
private List<String> processList = Arrays.asList(processArray);
public static void main(String[] args ) {
ExecutorService startUpExecutor = Executors.newFixedThreadPool(3);
ExecutorService cleanUpExecutor = Executors.newFixedThreadPool(3);
CompletionService<String> startUpCompletionService = new ExecutorCompletionService<>(startUpExecutor);
CompletionService<String> cleanUpCompletionService = new ExecutorCompletionService<>(cleanUpExecutor);
List<Future<String>> cleanupFutures = new ArrayList<Future<String>>();
List<Future<String>> startupFutures = new ArrayList<Future<String>>();
ProcessController myApp = new ProcessController();
int i = 0;
while (i++ < 3) {
System.out.println("**********Starting Iteration " + i + "************* =====> ");
if (!cleanupFutures.isEmpty()) cleanupFutures.clear();
myApp.processList.forEach(process -> cleanupFutures.add(cleanUpCompletionService.submit(new CleanupTask(process))));
myApp.processList.forEach(process -> startupFutures.add(startUpCompletionService.submit(new StartupTask(process))));
for (Future<String> f : cleanupFutures) {
try {
String result = cleanUpCompletionService.take().get();
System.out.println("Result from Cleanup thread : " + result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
for (Future<String> f1 : startupFutures) {
try {
String result = startUpCompletionService.take().get();
System.out.println("Result from startup thread : " + result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
System.out.println("**********Finished Iteration " + i + "************* =====> ");
}
startUpExecutor.shutdown();
cleanUpExecutor.shutdown();
}
}
CleanupTask class
public class CleanupTask implements Callable<String> {
private String task;
public CleanupTask(String task) {
this.task = task;
}
#Override
public String call() throws Exception {
checkIfAnyFinished();
return "finished clean up processing for " + getThreadId();
}
private void checkIfAnyFinished( )
{
System.out.println( getThreadId() + " Checking if task " + this.task + " is finished");
try {
isFinished();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void isFinished() throws InterruptedException {
Thread.sleep(1000*4);
}
private String getThreadId()
{
return Thread.currentThread().getName();
}
}
Startup Task class
public class StartupTask implements Callable<String> {
private String processSchedule ;
public StartupTask(String processSchedule) {
this.processSchedule = processSchedule;
}
#Override
public String call() {
scheduleifdue();
return "finished start up up processing for " + getThreadId();
}
private void scheduleifdue()
{
System.out.println(getThreadId() + " Checking " + this.processSchedule + " is due or not");
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private String getThreadId()
{
return Thread.currentThread().getName();
}
}
Above code successfully complete iteration 1 and start 2nd iteration . But it never finish and keeps running.
When I run the same application only with one task( either cleanup or startup) then it run without any issues. I'm not sure what is causing issue.

Java allowing for each thread to complete to print out in order

I'm trying to print out in order my Log statements instead of randomly after each ping? Should I use wait and notify from object class to allow each thread to finish? Not sure how to go about this.
Main class
public class Main
{
public static void main(String[] args)
throws InterruptedException, ExecutionException, IOException
{
Scan4SMB scan4Servers = new Scan4SMB();
List<String> networkNames = scan4Servers.doScan();
for (String networkName : networkNames)
{
LOG.CONSOLE.debug(networkName);
}
}
}
Scan class
public class Scan4SMB
{
private final int THREADS = 256;
private final int SMB_PORT = 445;
private List<String> smbNames = new ArrayList<String>();
private List<String> foundDevicesArray = new CopyOnWriteArrayList<String>();
private byte[] ip;
Scan4Servers() throws UnknownHostException
{
// this code assumes IPv4 is used
ip = Inet4Address.getLocalHost().getAddress();
LOG.CONSOLE.debug("LocalHost ip: " + ip);
}
Scan4Servers(Inet4Address address) throws UnknownHostException
{
ip = address.getAddress();
LOG.CONSOLE.debug("LocalHost IP: " + ip);
}
protected List<String> doScan() throws IOException
{
LOG.CONSOLE.debug("Start scanning");
ExecutorService executor = Executors.newFixedThreadPool(THREADS);
for (int i = 1; i <= 254; i++)
{
ip[3] = (byte) i;
InetAddress address = null;
try
{
address = InetAddress.getByAddress(ip);
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
executor.execute(pingRunnable(address));
}
LOG.CONSOLE.debug("Waiting for executor to terminate...");
executor.shutdown();
try
{
executor.awaitTermination(1000, TimeUnit.MILLISECONDS);
}
catch (InterruptedException ignored)
{
}
LOG.CONSOLE.debug("Scan finished");
return smbNames;
}
private Runnable pingRunnable(final InetAddress address) {
return new Runnable() {
public void run() {
LOG.CONSOLE.debug("Pinging " + address + "...");
try {
Socket socket = new Socket(address, SMB_PORT);
LOG.CONSOLE.debug("Connection: " + socket.toString());
if (socket.isConnected()) {
LOG.CONSOLE.debug("connected " + address.toString());
String ipString = address.toString().substring(1,
address.toString().length());
NbtAddress[] addr = NbtAddress
.getAllByAddress(ipString);
String NETNAME = addr[0].firstCalledName();
// String NETNAME1 =
// addr[0].nextCalledName();
smbNames.add(NETNAME);
LOG.CONSOLE.debug("NETNAME " + NETNAME);
LOG.CONSOLE.debug("addr " + addr);
foundDevicesArray.add(address.toString());
LOG.CONSOLE.debug("hostname added to found "
+ address.toString());
socket.close();
}
socket.close();
} catch (UnknownHostException e) {
// LOG.CONSOLE.debug("Not found", e);
} catch (IOException e) {
// LOG.CONSOLE.debug("IO Error", e);
}
}
};
}
protected List<String> getList()
{
return smbNames;
}
}
There are many ways to do it. Here's one possible approach using a CountDownLatch -- a simple but versatile way to coordinate threads. I modified your pingRunnable to accept 2 latches. It will wait for the first latch before before printing any output. It will clear the second latch after it's done.
This way every Runnable will wait for the previous one to be done before printing anything. The scanning will still occur in parallel but the output will be synchronized.
Here's the modified loop in doScan method:
CountDownLatch lastLatch = new CountDownLatch(0);
for (int i = 1; i <= 254; i++) {
ip[3] = (byte) i;
InetAddress address = null;
try {
address = InetAddress.getByAddress(ip);
} catch (UnknownHostException e) {
e.printStackTrace();
}
CountDownLatch nextLatch = new CountDownLatch(1);
executor.execute(pingRunnable(address, lastLatch, nextLatch));
lastLatch = nextLatch;
}
And Here's the modified pingRunnable:
private Runnable pingRunnable(final InetAddress address, CountDownLatch waitFor, CountDownLatch clearWhenDone) {
return new Runnable() {
public void run() {
try {
Socket socket = new Socket(address, SMB_PORT);
waitFor.await(); // wait for all previous runners to log their output
LOG.CONSOLE.debug("Connection: " + socket.toString());
if (socket.isConnected()) {
LOG.CONSOLE.debug("connected " + address.toString());
String ipString = address.toString().substring(1,
address.toString().length());
NbtAddress[] addr = NbtAddress
.getAllByAddress(ipString);
String NETNAME = addr[0].firstCalledName();
// String NETNAME1 =
// addr[0].nextCalledName();
smbNames.add(NETNAME);
LOG.CONSOLE.debug("NETNAME " + NETNAME);
LOG.CONSOLE.debug("addr " + addr);
foundDevicesArray.add(address.toString());
LOG.CONSOLE.debug("hostname added to found "
+ address.toString());
socket.close();
}
socket.close();
} catch (UnknownHostException e) {
// LOG.CONSOLE.debug("Not found", e);
} catch (IOException e) {
// LOG.CONSOLE.debug("IO Error", e);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
} finally {
clearWhenDone.countDown(); // signal to the next Runnable that we are done
}
}
};
}
My understanding is that you want to run a bunch of tasks in parallel, (the ping), but you want the log messages to print in the order the tasks were submitted to the executor, but only after they are done.
We can do that.
// I'm taking some liberty with your code, so the concepts are highlighted
ExecutorService exec = ....;
// Important thing is to have a list of result futures
List<Future<String>> results = new ArrayList<>();
// we have some way to generate our work. For loop like above is fine.
List<String> addresses = imagineWeHaveAListOfAddresses();
for( String address : addresses ) {
// here we record the future returned by the ExecutorService
results.add(exec.submit(pingRunnable(address), address);
}
// result.get() is blocking, so we'll print the addresses in the same order we submitted them.
for( Future<String> result : results ) {
LOG.info("Finished address: " + result.get());
}
I hope that helps.

How pass these new messages to another class

Now basically I have created three classes.
public void run() {
int seqId = 0;
while(true) {
List<KamMessage> list = null;
try {
list = fullPoll(seqId);
} catch (Exception e1) {
e1.printStackTrace();
}
if (!list.isEmpty()) {
seqId = list.get(0).getSequence();
incomingMessages.addAll(list);
System.out.println("waiting 3 seconds");
System.out.println("new incoming message");
}
try {
Thread.sleep(3000);
System.out.println("new incoming message");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public List<KamMessage> fullPoll(int lastSeq) throws Exception {
Statement st = dbConnection.createStatement();
ResultSet rs = st.executeQuery("select * from msg_new_to_bde where ACTION = 804 and SEQ >" +
lastSeq + "order by SEQ DESC");
List<KamMessage> pojoCol = new ArrayList<KamMessage>();
while (rs.next()) {
KamMessage filedClass = convertRecordsetToPojo(rs);
pojoCol.add(filedClass);
}
for (KamMessage pojoClass : pojoCol) {
System.out.print(" " + pojoClass.getSequence());
System.out.print(" " + pojoClass.getTableName());
System.out.print(" " + pojoClass.getAction());
System.out.print(" " + pojoClass.getKeyInfo1());
System.out.print(" " + pojoClass.getKeyInfo2());
System.out.println(" " + pojoClass.getEntryTime());
}
return pojoCol;
}
The following are the classes:
1.Poller- does the Polling and Passes the new data from db to controller
2.Controller- this class has a thread Pool, which simultaneously calls the Poller and has the new data to be requested from processor
3.Processor- this class has to look for new data, process it and return it to controller.
So now my problem is how to implement the third phase...
Here is my controller class:
public class RunnableController {
/** Here This Queue initializes the DB and have the collection of incoming message
*
*/
private static Collection<KpiMessage> incomingQueue = new ArrayList<KpiMessage>();
private Connection dbConncetion;
public ExecutorService threadExecutor;
private void initializeDb()
{
//catching exception must be adapted - generic type Exception prohibited
DBhandler conn = new DBhandler();
try {
dbConncetion = conn.initializeDB();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void initialiseThreads()
{
try {
threadExecutor = Executors.newFixedThreadPool(10);
PollingSynchronizer read = new PollingSynchronizer(incomingQueue, dbConncetion);
threadExecutor.submit(read);
}catch (Exception e){
e.printStackTrace();
}
}
#SuppressWarnings("unused")
private void shutDownThreads()
{
try {
threadExecutor.shutdown();
//DB handling should be moved to separate DB class
dbConncetion.close();
}catch (Exception e){
e.printStackTrace();
}
}
/** Here This Queue passes the messages and have the collection of outgoing message
*
*/
//private Collection<KpiMessage> outgingQueue = new ArrayList<KpiMessage>();
//have to implement something here for future
public static void main(String[] args) throws InterruptedException {
RunnableController controller = new RunnableController();
System.out.println(incomingQueue.size());
controller.initializeDb();
controller.initialiseThreads();
Thread.sleep(3000);
System.out.println("Polling");
}
}
I would recommend using a BlockingQueue for doing so, instead of a simple ArrayList. Just change the type of your incomingQueue variable. Then you can have another thread (or a thread pool) doing something like
//pseudocode
while (true) {
// it polls data from the incomingQueue that shares with the producers
KpiMessage message = this.incomingQueue.take()
//Then process the message and produces an output... you can put that output in a different queue as well for other part of the code to pick it up
}
A good example on BlockingQueues can be found here http://www.javamex.com/tutorials/blockingqueue_example.shtml

Categories