03-01-2010 09:20 PM - edited 03-01-2010 09:23 PM
My app connects to our server via SocketConnection. The server sends out a formatted set of strings that contains the latest Stock trade. So whenever a new trade happens, the server will send out an individual Stock Quote of that trade. Through an InputStream I am able to read that information and place each character in a StringBuffer that is referenced by Threads. By parsing based on char3 I am able to determine a set of stock quote/information.
char1 - to separate data char3 - means end of a stock quote/information
sample stock quote format sent out by our server:
stock_quote_name(char 1)some_data(char1)some_data(char1)(char3)
My app then parses that stock quote to compare certain data and formats it how it will look like when displayed in the screen. When trades happen gradually(slow) the app works perfectly. However..
Problem: When trades happen too quickly and almost at the same time, My app is not able to handle the information sent efficiently. The StringBuffer has its contents combined with the next trade. Meaning Two stock information in one StringBuffer.
field should be: Stock_quote_name some_data some_data
sample of what's happening: Stock_quote_name some_data some_dataStock_quote_name some_data some_data
here's my code for this part:
while (-1 != (data = is.read()))
{
sb.append((char)data);
while(3 != (data = is.read()))
{
sb.append((char)data);
}
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
try
{
/*
*while data from input stream is not equal to -1 or 3 (end of quote set) continue to read.
*
*/
Synchronized(UiApplication.getEventLock(
{
SetStringBuffer(sb);
DisplayStringBuffer();
RefreshStringBuffer();
}
} catch (Exception e)
{
System.out.println("Error in setting stringbuffer: " + e.toString());
}
}
});
}
public synchronized void DisplayStringBuffer()
{
try
{
//parse the stock information
}
catch(Exception ex)
{
System.out.println("error in DisplayStringBuffer(): " + ex.toString());
}
}
public synchronized void SetStringBuffer(StringBuffer dataBuffer)
{
this.sb =dataBuffer;
System.out.println(sb);
}
public synchronized void RefreshStringBuffer()
{
this.sb.delete(0, this.sb.length());
}
From what I can see, when trades happen very fast, The StringBuffer is not refreshed immediately and still has the contents of the previous trade, when i try to put new data.
My Question is: How do i synchronize the reuse of the stringbuffer and append new characters without the next information being appended to the first content and deadlocks
Solved! Go to Solution.
03-01-2010 09:48 PM
invokeLater is not guaranteed to run immediately, which is probably why you're seeing this. Why don't you use an actual additional thread for this and signal across threads?
03-02-2010 01:53 AM
well this is already happening inside a thread
03-02-2010 02:10 AM
Then you don't need to use invokeLater. You are clearing the buffer on the Runnable, and if the Runnable doesn't get executed immediately before you put more data into it, you will see the problem you are experiencing.
What it sounds like you want is a traditional consumer/producer pattern here, which should work properly.
03-02-2010 10:01 PM
thanks ydaraishy.. here's my final code:
while (-1 != (data = is.read()))
{
sb.append((char)data);
while(3 != (data = is.read()))
{
sb.append((char)data);
}
DisplayStringBuffer(sb);
RefreshStringBuffer();
}
public synchronized void DisplayStringBuffer(StringBuffer dataBuffer)
{
System.out.println(dataBuffer);
synchronized(UiApplication.getEventLock())
{
//parse String dataBuffer
}
}
public synchronized void RefreshStringBuffer()
{
this.sb.delete(0, this.sb.length());
}