Java Future object with Runnable interface - java

I have to do an assignment where I have to implement a background thread logger for a web service, for the logger we got some skeleton code where we have a run method and a method that returns a future object. For logging of activities we have to implement write ahead logging, I managed to start a new thread for the logger and I send it the command to log something when I execute an insert/update command in the web service (the web service implements a key to values map), but I can`t manage to make the main thread wait for the logging thread to finish logging. Does anybody have any suggestions? Maybe I am doing something wrong?
public class IndexImpl implements Index<KeyImpl,ValueListImpl>
{
private Thread log_thread;
private MyLogger log;
/*
* in out pair, the long refers to the initial memory address that our data
* has been saved too, and the integer refers to the length of the data in the file
*/
private HashMap<KeyImpl,Pair<Long,Integer>> m;
private long endAddr;
public IndexImpl()
{
valSer = new ValueSerializerImpl();
endAddr = 0;
m = new HashMap<KeyImpl,Pair<Long,Integer>>();
this.log= new MyLogger();
this.log_thread= new Thread(log);
log_thread.start();
}
public void insert(KeyImpl k, ValueListImpl v) throws KeyAlreadyPresentException, IOException {
locker.WriteLock(k);
try {
if (m.containsKey(k)) {
throw new KeyAlreadyPresentException(k);
}
else {
//LOGGING
Object[] array = new Object[3]; // Key, Old Value List, New Value List
array[0]= k.toString(); //Key
array[1]= null; // Old value list
array[2]= v; // New value list
LogRecord l = new LogRecord(MyKeyValueBaseLog.class, "insert", array);
FutureLog<LogRecord> future = (FutureLog<LogRecord>) log.logRequest(l);
System.out.println("Inserting a new key " + k.getKey());
future.get();
long tempEndAddr;
byte[] temp = valSer.toByteArray(v);
//we are using the ReentrantReadWriteLock implementation found in java
write.lock();
try{
tempEndAddr = endAddr;
endAddr += temp.length;
}
finally{
write.unlock();
}
store.write(tempEndAddr, temp);
m.put(k, new Pair<Long, Integer>(tempEndAddr,temp.length));
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
locker.WriteUnlock(k);
}
}
And the code for the logger is :
public class MyLogger implements Logger {
private ArrayList<LogRecord> log = new ArrayList<LogRecord>(100);
public MyLogger()
{
}
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("This is the logger thread! " + Thread.currentThread());
}
#Override
public Future<?> logRequest(LogRecord record) {
// TODO Auto-generated method stub
this.log.add(record);
System.out.println("Record added to log! operation: " + record.getMethodName() );
FutureLog<LogRecord> future = new FutureLog();
return future;
}
}

Your logger thread is started and will exit immediately
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("This is the logger thread! " + Thread.currentThread());
}
Instead, you need to loop in this method, writing log records as they come in. I would perhaps suggest reading from a BlockingQueue, and the method logRequest() should add log records to this queue. That way your run() method will just wait on the queue (using the take() method provided by the queue) and write out each record as it takes it off the queue.
You'll need to be able to stop this, and perhaps interrupting the thread is a solution here.
All of the above is simply one implementation choice. The fundamental problem you have is that your thread starts/stops almost instantaneously.

Related

static varibale cant be changed from a thread

in the below code, I create the class FMSHandler to process a string value passed to it from the main method as follwos
while (true) {
fmsHandler.process("param1_" + (++cnt) + ", param2_" + (cnt));
}
what i want to do is, to allow the processing to be performed every 3 seconds. or in other words, every 3 seconds i read the message passed from the main throught the previously mentioned code and perform
further processing. to do so, i created a static boolean variable called sIsProcessing to regulate the processing. this static variable is initially false and as long as there is
a message being processed it will be true and it will be set back to false when the thread the performs processing finihes as shown in the code below.
the problem i am facing is, despite the while-loop runs for ever, the processing is applied once and it is NOT repeated every 3 seconds as i expected it.
please have alook at the code and let me know where is the mistake
main:
public class Main {
private final static String TAG = Main.class.getSimpleName();
public static void main(String[] args) {
FMSHandler fmsHandler = new FMSHandler();
long startTime = TimeUtils.getTSSec();
int cnt = 0;
while (true) {
fmsHandler.process("param1_" + (++cnt) + ", param2_" + (cnt));
}
}
}
FMSHandler :
public class FMSHandler {
private final static String TAG = FMSHandler.class.getSimpleName();
private static boolean sIsProcessing = false;
private static int sCnt = 0;
public void process(String fmsMsg) {
if (!sIsProcessing) {
sIsProcessing = true;
Log.w(TAG, "FMSHandler", "new task to be processed");
new HandlerThread(HandlerThread.class.getSimpleName() + "_" + (FMSHandler.sCnt++), fmsMsg).start();
}
}
class HandlerThread extends Thread {
private String[] mSplittedFMS = null;
private String mThreadName = "";
public HandlerThread(String threadName, String fmsMsg) {
// TODO Auto-generated constructor stub
this.setName(threadName);
this.mSplittedFMS = this.toArray(fmsMsg);
}
private String[] toArray(String fmsMsg) {
// TODO Auto-generated method stub
return fmsMsg.split(",");
}
public void run() {
Log.w(TAG, "HandlerThread.run()", this.getName() + " started");
for (int i = 0; i < this.mSplittedFMS.length; i++) {
Log.i(TAG, "HandlerThread.run()", "this.mSplittedFMS: " + this.mSplittedFMS[i]);
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.w(TAG, "HandlerThread.run()", this.getName() + " finished");
sIsProcessing = false;
}
}
}
You should declare the sIsProcessing variable as volatile or use an AtomicBoolean.
Also, currently, a lot of the messages passed to process(...) will be skipped, I'm not sure if that is your intention.
If you want to prevent messages from being skipped you will need to use synchronization to block the loop from the main thread while a message is being processed.
My suggestion will be to completely rewrite this and use a Timer and some kind of queue from the concurrency package like ArrayBlockingQueue.
Here is an example:
public static final ArrayBlockingQueue<String> messages = new ArrayBlockingQueue<>(100);
public static final AtomicBoolean keepRunning = new AtomicBoolean(true);
.....
new Thread(new Runnable(){
public void run(){
while(keepRunning.get()){
String message = messages.take();// blocks until a message is avaiable
synchronized(Thread.currentThread()){
Thread.currentThread().wait(3000);// pause 3 seconds before starting to process the next message.
}
}
}
}).start();
// add messages from some other class;
MessagesProcessor.messages.add("some message");

Sending and receiving objects using sockets and threads not working properly

I am currently creating a service allowing to send objects from a client to a server and vice-versa, but experiencing an issue that I unfortunately cannot explain and fix.
First of all, here are the useful classes (I haven't put all methods such as getters and setters in this post).
/**
* This launcher creates a NetworkInterface, waits for a connection, sends a message to the connected client and waits for an incoming message
*
*/
public class ServerLauncher {
public static void main(String[] args) {
try {
NetworkSystem n = new NetworkSystem(4096);
n.startServerManager();
while (n.getCommunications().isEmpty()) {
// this line is unexpectedly magic
System.out.println("Waiting for a new connection...");
}
do {
n.getCommunications().get(0).send(new String("Hello, are you available?"));
} while (n.getCommunications().get(0).getReceiveManager().getReadObjects().isEmpty());
System.out.println(n.getCommunications().get(0).getReceiveManager().getReadObjects().get(0));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* This launcher creates a NetworkSystem, connects to the server, waits for an incoming message and anwers back
*
*/
public class ClientLauncher {
public static void main(String[] args) {
try {
NetworkSystem n = new NetworkSystem(8192);
n.instanciateCommunication(new Socket(InetAddress.getLocalHost(), 4096));
while (n.getCommunications().get(0).getReceiveManager().getReadObjects().isEmpty()) {
// this line is unexpectedly magic
System.out.println("Waiting for an object...");
}
System.out.println(n.getCommunications().get(0).getReceiveManager().getReadObjects().get(0));
n.getCommunications().get(0).getSendManager().send(new String("No, I am not! We will talk later..."));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* This class handles every incoming messages.
*/
public class ReceiveManager implements Runnable {
private ObjectInputStream inputStream;
private CommunicationManager communicationManager;
private List readObjects;
private boolean receive;
public ReceiveManager(CommunicationManager communicationManager) throws IOException {
this.communicationManager = communicationManager;
this.inputStream = new ObjectInputStream(this.communicationManager.getSocket().getInputStream());
this.readObjects = new ArrayList();
this.receive = true;
}
#Override
public void run() {
Object object = null;
try {
while ((object = this.inputStream.readObject()) != null && this.hasToReceive()) {
this.readObjects.add(object);
}
} catch (ClassNotFoundException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
this.setContinueToReceive(false);
}
}
private boolean hasToReceive() {
return this.receive;
}
public void setContinueToReceive(boolean value) {
this.receive = value;
}
}
/**
* This class allows the user to send messages
*/
public class SendManager {
private ObjectOutputStream outputStream;
private CommunicationManager communicationManager;
public SendManager(CommunicationManager communicationManager) throws IOException {
this.communicationManager = communicationManager;
this.outputStream = new ObjectOutputStream(this.communicationManager.getSocket().getOutputStream());
}
public void send(Object object) throws IOException {
this.outputStream.writeObject(object);
this.outputStream.flush();
}
}
So basically, as you may have noticed in the ServerLauncher and the ClientLauncher, there are two "magic" instructions. When those two lines are commented and I run the server then the client, nothing happens. The server and the client are simply running and never stop. However, when I uncomment these two magic lines, every works like a charm: messages are properly sent and received.
Would you guys know the reason of this unexpected behaviour ?
Oh yeah, I forgot, if you guys want me to upload everything to test the project or whatever, just tell me :-)
You're starving the CPU with those spin loops. You should sleep or wait while the queues are empty, or better still just take()from blocking queues.
NB Your loop condition isn't correct:
readObject() doesn't return null at end of stream. It throws EOFException.
You should also test hasToReceive() before calling readObject() rather than afterwards. Otherwise you always do an extra read.

How can I make the thread sleep for a while and then process all the messages?

I'm writing an Android app that uses two threads. One is UI thread and the other handles server communication. Is it possible for the other thread to wait for a specified amount of time and then process all the messages that have arrived and then wait again?
I need this so that I can collect different data and send it to server in one session.
I've build my thread with HandlerThread but now I'm stuck. Can anyone point me to the right direction?
This is the code I'm using inside the second thread:
public synchronized void waitUntilReady() {
serverHandler = new Handler(getLooper()){
public void handleMessage(Message msg) { // msg queue
switch(msg.what) {
case TEST_MESSAGE:
testMessage(msg);
break;
case UI_MESSAGE:
break;
case SERVER_MESSAGE:
break;
default:
System.out.println(msg.obj != null ? msg.obj.getClass().getName() : "is null");
break;
}
}
};
}
EDIT:
I resolved my issue by going with Thread instead of HandlerThread and using queue.
I'm new to programming so I apologize for any horrenous errors but here's the code I ended up using.
public class ServiceThread extends Thread {
// TODO maybe set the thread priority to background?
static ServiceThread sThread = new ServiceThread(); // service thread instance
private volatile Handler mainHandler;
//
public Thread mainThread;
private boolean OK = true;
public Queue<MessageService> msgQueue;
private ThreadPoolExecutor exec;
private ServiceThread() { }
#Override
public void run() {
synchronized (this){
msgQueue = new ConcurrentLinkedQueue<MessageService>();
notifyAll();
}
mainHandler = new Handler(Looper.getMainLooper());
ThreadPoolExecutor exPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
exec = exPool;
// MAIN LOOP
try {
while(OK) {
getMessagesFromQueue();
Thread.sleep(3000);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//end of loop
}
public void ProcessMessage(MessageService message) {
System.err.println("ProcessMessage with command: " + message.command);
}
/** Called from the Main thread. Waits until msgQueue is instantiated and then passes the reference
* #return Message Queue
*/
public Queue<MessageService> sendQueue() {
synchronized (this){
while(msgQueue == null) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block -- move the try block!
e.printStackTrace();
}
}
}
return msgQueue;
}
public void setOkFalse () {
if (OK == true)
OK = false;
}
// Message handling methods
/** Priority message from UI thread, processed in another thread ASAP.
* Should be used on commands like getBigPicture or getPics when cached pics are running out
* or upload picture etc.
* #param message - Message should always be MessageService class
* TODO check that it really is.
*/
public void prioTask (MessageService message) {
final MessageService taskMsg = message;
Runnable task = new Runnable() {
#Override
public void run(){
ProcessMessage(taskMsg);
}
};
exec.execute(task);
}
/**
* Gets messages from queue, puts them in the list, saves the number of messages retrieved
* and sends them to MessageService.handler(int commands, list messageList)
* (method parameters may change and probably will =) )
*/
public void getMessagesFromQueue() {
int commands = 0;
ArrayList <MessageService> msgList = new ArrayList <MessageService>();
while(!msgQueue.isEmpty()) {
if(msgQueue.peek() instanceof MessageService) {
//put into list?
msgList.add(msgQueue.remove());
commands++;
} else {
//Wrong type of message
msgQueue.remove();
System.err.println("getMessagesFromQueue: Message not" +
" instanceof MessageService, this shouldn't happen!");
}
}
if (commands > 0) {
HTTPConnection conn;
try {
conn = new HTTPConnection();
MessageService.handleSend(commands, msgList, conn);
conn.disconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
P.S. This is also my first post here. Should I mark it solved or something? How?

How to achieve multi threading while one thread is at sleep mode

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();

Invoke more than one webservice using separate thread in java?

I have to call more than one webservice in one method each webservice is executed by separate thread in concurrent/parellel. Every web service will return one ArrayList. Note: may chance some webservices will fail or take more time process response in this case i have to skip these failure result. How can I achieve this? I tried this sample code.
public class MultiThreadsEx{
public class Task implements Runnable {
private Object result;
private String id;
int maxRowCount = 0;
public Task(String id) {
this.id = id;
}
public Object getResult() {
return result;
}
public void run() {
try {
System.out.println("Running id=" + id+" at "+Utilities.getCurrentJavaDate("DD/MM/YYYY HH:MM:SS"));
if(id.equalsIgnoreCase("1")){
/**Getting Details from Amazon WS*/
maxRowCount = AmazonUtils.getweather(cityname);
}else if(id.equalsIgnoreCase("2")){
/**Getting Details from Google WS* /
maxRowCount = GoogleUtils.getWeather(cityName);
}
// call web service
//Thread.sleep(1000);
//result = id + " more";
result = maxRowCount;
} catch (InterruptedException e) {
// TODO do something with the error
throw new RuntimeException("caught InterruptedException", e);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void runInParallel(Runnable runnable1, Runnable runnable2) {
try {
Thread t1 = new Thread(runnable1);
Thread t2 = new Thread(runnable2);
t1.start();
t2.start();
} catch (Exception e) {
// TODO do something nice with exception
throw new RuntimeException("caught InterruptedException", e);
}
}
public void foo() {
try {
Task task1 = new Task("1");
Task task2 = new Task("2");
runInParallel(task1, task2);
System.out.println("task1 = " + task1.getResult()+" at "+Utilities.getCurrentJavaDate("DD/MM/YYYY HH:MM:SS"));
System.out.println("task2 = " + task2.getResult()+" at "+Utilities.getCurrentJavaDate("DD/MM/YYYY HH:MM:SS"));
} catch (Exception e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
But run() return type is void so how can return result? Examples are highly appreciated. I am new to multithread/concurrent threads concept so if I'm doing anything wrong, please point me in the right direction.
Consider replacing Runnable - run with Callable - call. This will allow you to return a result from your thread task:
public class Task implements Callable<Object> {
private Object result;
public Object call() {
// compute result
return result;
}
}
Now use an ExecutorService:
public static void runInParallel(Callable<Object> c1, Callable<Object> c2) {
ExecutorService exec = Executors.newFixedThreadPool(2);
Future<Object> f1 = exec.submit(c1);
Future<Object> f2 = exec.submit(c2);
}
Later in the code you can use f1.get() and f2.get() to wait for the results of the tasks.
The usual way to communicate the results of a Runnable back to the object which created it is by passing the creating object to the constructor of the Runnable. When the task is finished, you can call a method in the creating object and pass the result data.

Categories