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
Related
I'm trying to create an object in one class then use that object in another class but each time I try to use it it just says the value is null
Customer cus = new Customer();
ServerSocket s = null;
public AddCustomer() {
}
public void getCustomerDetail() {
String back = " ";
{
try {
s = new ServerSocket(5433);
} catch (IOException e) {
System.out.println("Error:" + e.getMessage());
System.exit(0);
}
while (back.equals(" ")) {
try {
Socket s1 = s.accept();
System.out.println("Connection established at port 5433");
InputStream is = s1.getInputStream();
ObjectInputStream dis = new ObjectInputStream(is);
System.out.println("Getting data...");
cus = (Customer)dis.readObject();
System.out.println(cus.toString());
System.out.println(cus.getName());
dis.close();
s1.close();
System.out.println("Connection closed.");
} catch (ConnectException connExcep) {
System.out.println("1Error: " + connExcep.getMessage());
} catch (IOException ioExcep) {
System.out.println("2Error: " + ioExcep.getMessage());
} catch (Exception e) {
System.out.println("3Error: " + e.getMessage());
}
new AddCustomer().addCustomerToDB();
}
}
}
public void addCustomerToDB() {
System.out.println("start ");
Connection connection = null;
Statement statement = null;
int check = 1;
System.out.println(cus.getName()+"dadawd");
}
When I print out the value of cus.getName() it just gives me null but when I print it out in getCustomerDetail it gives me the correct value.
dis.readObject returns an object with the values in it.
Depends on what you are doing in the getName function and in the constructor.
Maybe in getCustomerDetails() you are setting the values in the input stream. But the default constructor doesn't do anything with name variable.
It looks like the issue of packaging. Try below code.
public class AddCustomer {
public static void main(String[] args) {
new AddCustomer().getCustomerDetail();
}
Customer cus = new Customer();
public void getCustomerDetail() {
String back = " ";
{
while (back.equals(" ")) {
try {
System.out.println(cus.toString());
System.out.println(cus.getName());
System.out.println("Connection closed.");
} catch (Exception e) {
System.out.println("3Error: " + e.getMessage());
}
new AddCustomer().addCustomerToDB();
break;
}
}
}
public void addCustomerToDB() {
System.out.println(cus.getName()+"dadawd");
}
}
class Customer{
private String name="ABC";
String getName() {
return name;
}
}
We found here one issue you have to create "Customer cus = new Customer();" this object under main() function like as
public class AddCustomer {
public static void main(String[] args) {
Customer cus = new Customer();
new AddCustomer().getCustomerDetail();
}
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");
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.
I am trying to do multi-threading here, now I have to update my database using DbHandler class
The program execution begins in a controller class which has a main method and a thread pool:
public class RunnableController {
// Main method
public static void main(String[] args) throws InterruptedException {
try {
RunnableController controller = new RunnableController();
controller.initializeDb();
controller.initialiseThreads();
System.out.println("Polling");
} catch (Exception e) {
e.printStackTrace();
}
}
private void initialUpdate()
{
DBhandler dbhandler = new DBhandler();
dbhandler.updateDb(getOutgoingQueue());
}
private void initialiseThreads() {
try {
threadExecutorRead = Executors.newFixedThreadPool(10);
PollingSynchronizer read = new PollingSynchronizer(incomingQueue, dbConncetion);
threadExecutorRead.submit(read);
} catch (Exception e){
e.printStackTrace();
}
}
}
My poller class which fetches new data and should do updating simulateously:
public class PollingSynchronizer implements Runnable {
public PollingSynchronizer(Collection<KamMessage> incomingQueue,
Connection dbConnection) {
super();
this.incomingQueue = incomingQueue;
this.dbConnection = dbConnection;
}
private int seqId;
public int getSeqId() {
return seqId;
}
public void setSeqId(int seqId) {
this.seqId = seqId;
}
// The method which runs Polling action and record the time at which it is done
public void run() {
int seqId = 0;
while (true) {
List<KamMessage> list = null;
try {
list = fullPoll(seqId);
if (!list.isEmpty()) {
seqId = list.get(0).getSequence();
incomingQueue.addAll(list);
this.outgoingQueue = incomingQueue;
System.out.println("waiting 3 seconds");
System.out.println("new incoming message");
Thread.sleep(3000);//at this wait I should execute run()
//when I debug my execution stops here and throws " Class not found Exception "
// its does not enters the message processor class
MessageProcessor processor = new MessageProcessor() {
//the run method which should fetch the message processor class.
final public void run() {
RunnableController.setOutgoingQueue(generate(outgoingQueue));
}
};
new Thread(processor).start();
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}
My message processor class:
public class MessageProcessor implements Runnable {
private Collection<KpiMessage> fetchedMessages;
private Connection dbConnection;
Statement st = null;
ResultSet rs = null;
PreparedStatement pstmt = null;
private Collection<KamMessage> outgoingQueue;
public Collection<KamMessage> MessageProcessor(Collection<KamMessage> outgoingQueue){
this.outgoingQueue = outgoingQueue;
this.dbConnection = dbConnection;
return outgoingQueue;
}
/**
* Method for updating new values into database in preference for dummy processing of message
* #param outgoingQueue
* #return
*/
#SuppressWarnings("javadoc")
public Collection<KamMessage> generate(Collection<KamMessage> outgoingQueue)
{
for (KamMessage pojoClass : outgoingQueue) {
KamMessage updatedValue = createKamMsg804(pojoClass);
System.out.print(" " + pojoClass.getSequence());
System.out.print(" " + pojoClass.getTableName());
System.out.print(" " + pojoClass.getAction());
System.out.print(" " + updatedValue.getKeyInfo1());
System.out.print(" " + updatedValue.getKeyInfo2());
System.out.println(" " + pojoClass.getEntryTime());
}
return outgoingQueue;
}
/**
*
* #param pojoClass
* #return msg
*/
public KamMessage createKamMsg804(KamMessage pojoClass)
{
if(pojoClass.getAction() == 804){
pojoClass.setKeyInfo1("ENTITYKEY9");
pojoClass.setKeyInfo2("STATUSKEY9");
}
return pojoClass;
}
private KamMessage convertRecordsetToPojo(ResultSet rs) throws SQLException {
KamMessage msg = new KamMessage();
int sequence = rs.getInt("SEQ");
msg.setSequence(sequence);
String tablename = rs.getString("TABLENAME");
msg.setTableName(tablename);
Timestamp entrytime = rs.getTimestamp("ENTRYTIME");
Date entryTime = new Date(entrytime.getTime());
msg.setEntryTime(entryTime);
Timestamp processingtime=rs.getTimestamp("PROCESSINGTIME");
if(processingtime!=null){
Date processingTime = new Date(processingtime.getTime());
msg.setProcessingTime(processingTime);
}
String keyInfo1 = rs.getString("KEYINFO1");
msg.setKeyInfo1(keyInfo1);
String keyInfo2 = rs.getString("KEYINFO2");
msg.setKeyInfo2(keyInfo2);
return msg;
}
#Override
public void run() {
// TODO Auto-generated method stub
}
}
This is my DBhandler Class, which should do updating in database
public class DBhandler {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
PreparedStatement pstmt = null;
public DBhandler(){
super();
}
/**
* Method to initialize the database connection
* #return conn
* #throws Exception
*
*/
public Connection initializeDB() throws Exception {
System.out.println("JDBC connection");
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
conn = DriverManager.getConnection("jdbc:oracle:thin:#VM-SALES-
MB:1521:SALESDB1","bdeuser", "edb"); // Connection for Database SALES-DB1
return conn;
}
//The method for updating Database
public void updateDb(Collection<KpiMessage> updatedQueue){
for(KpiMessage pojoClass : updatedQueue){
//**How the query should be used so that it gets last sequence vale and Updates into
Database**
String query = "UPDATE msg_new_to_bde Set KEYINFO1= ?, KEYINFO2 = ? WHERE SEQ = and
action = 804";
}
}
/**
* Method for Closing the connection
* #throws Exception
*
*/
public void closeDB() throws Exception {
st.close();
conn.close();
}
}
I just need to Update the database using update query in this class(DbHAndler) by calling the updatedQueue in the controller class.
My program flow - I have three classes: 1.Controller 2.PollerSynchro 3.Msgprocessor
I have database records, which are converted into POJO form and stored in a Collection. With these POJOs my classes try to do multiprocessing and updating in a single stretch.
Controller - has the thread pool, initiates poller class with poll method - done
Poller - should poll for new incoming messages and stores it in incoming queue - done
MsgProcessor - should look for new incoming messages and pass them from outgoing queue to incoming queue - also done
DbHandler- which should update in the database.
Problem:
Now my problem is
I have to implement this update while the poll thread sleeps for 3 sec -Done
In my code for the second void run() method in the Poller class, the outgoing queue is not passed and fed to the messageprocessor class for updating. My flow of execution only just loops back to first run method and am getting Class exception-Resolved
How to Update this in the database in Dbhanler class
Please help me to solve these problems.
The exception seems to come from this line (is this MessageProcessor.java line 38?)
return (KpiMsg804) fetchedMessages;
The fetchedMessages at this point seem to be an ArrayList.
I have a problem where my class is performing the first run method after which it is not proceeding into a second, overidden run method.
The program execution beings in a controller class which has a main method and a thread pool:
public class RunnableController {
// Main method
public static void main(String[] args) throws InterruptedException {
try {
RunnableController controller = new RunnableController();
controller.initializeDb();
controller.initialiseThreads();
System.out.println("Polling");
} catch (Exception e) {
e.printStackTrace();
}
}
private void initialiseThreads() {
try {
threadExecutorRead = Executors.newFixedThreadPool(10);
PollingSynchronizer read = new PollingSynchronizer(incomingQueue, dbConncetion);
threadExecutorRead.submit(read);
} catch (Exception e){
e.printStackTrace();
}
}
}
My poller class which fetches new data and should do updating simulateously:
public class PollingSynchronizer implements Runnable {
public PollingSynchronizer(Collection<KamMessage> incomingQueue,
Connection dbConnection) {
super();
this.incomingQueue = incomingQueue;
this.dbConnection = dbConnection;
}
private int seqId;
public int getSeqId() {
return seqId;
}
public void setSeqId(int seqId) {
this.seqId = seqId;
}
// The method which runs Polling action and record the time at which it is done
public void run() {
int seqId = 0;
while (true) {
List<KamMessage> list = null;
try {
list = fullPoll(seqId);
if (!list.isEmpty()) {
seqId = list.get(0).getSequence();
incomingQueue.addAll(list);
this.outgoingQueue = incomingQueue;
System.out.println("waiting 3 seconds");
System.out.println("new incoming message");
Thread.sleep(3000);//at this wait I should execute run()
//when I debug my execution stops here and throws " Class not found Exception "
// its does not enters the message processor class
MessageProcessor processor = new MessageProcessor() {
//the run method which should fetch the message processor class.
final public void run() {
MessageProcessor(outgoingQueue).generate(outgoingQueue);
}
};
new Thread(processor).start();
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}
My message processor class:
public abstract class MessageProcessor implements Runnable {
private Connection dbConnection;
Statement st = null;
ResultSet rs = null;
PreparedStatement pstmt = null;
private Collection<KamMessage> outgoingQueue;
public KamMsg804 MessageProcessor(Collection<KamMessage> outgoingQueue,
Connection dbConnection) {
this.outgoingQueue = outgoingQueue;
this.dbConnection = dbConnection;
return (KpiMsg804) fetchedMessages;
}
public Collection<KamMessage> generate(Collection<KamMessage> outgoingQueue) {
while (true) {
try {
while (rs.next()) {
KamMessage filedClass = convertRecordsetToPojo(rs);
outgoingQueue.add(filedClass);
}
for (KamMessage pojoClass : outgoingQueue) {
KamMsg804 updatedValue = createKamMsg804(pojoClass);
System.out.print(" " + pojoClass.getSequence());
System.out.print(" " + pojoClass.getTableName());
System.out.print(" " + pojoClass.getAction());
System.out.print(" " + updatedValue.getKeyInfo1());
System.out.print(" " + updatedValue.getKeyInfo2());
System.out.println(" " + pojoClass.getEntryTime());
}
return outgoingQueue;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
My problem is exactly at the second run(9 method where I am getting exception in MessageProcessor class and it loops back to Polling.
How do I implement multithreading here, as when the thread sleeps for 3 seocnds in polling it should simultaneously update the database.
After which, how can the data be fed and updated back into the db.
My program flow - I have three classes:
1.Controller
2.PollerSynchro
3.Msgprocessor
I have database records, which are converted into POJO form and stored in a Collection. With these POJOs my classes try to do multiprocessing and updating in a single stretch.
Controller - has the thread pool, initiates poller class with poll method - done
Poller - should poll for new incoming messages and stores it in incoming queue - done
MsgProcessor - should look for new incoming messages and pass them from outgoing queue to incoming queue - also done
Problem:
Now my problem is
I have to implement this update while the poll thread sleeps for 3 sec,
In my code for the second void run() method in the Poller class, the outgoing queue is not passed and fed to the messageprocessor class for updating. My flow of execution only just loops back to first run method and am getting Class exception.
Please help me to solve these problems.
I can't sugar coat this, your code is a mess. However, as far as why your message processor code is not being executed, you never actually start the thread you created with this code:
MessageProcessor processor = new MessageProcessor() {
// the run method which should fetch the message processor class.
final public void run() {
MessageProcessor(outgoingQueue).generate(outgoingQueue);
}
};
Ignoring the confusingly named method being called, your code should look more like this:
Message processor = new MessageProcessor() {
// the run method which should fetch the message processor class.
final public void run() {
MessageProcessor(outgoingQueue).generate(outgoingQueue);
}
};
new Thread(processor).start();