I am running a java application in a TimerTask using the schedule method, i.e. it runs at certain intervals and if the timertask gets delayed it does not try to play catch-up. I want the program to run for as long as possible if not indefinitely. I am using Netbeans 7.3.
However, I find that after a few hours (sometimes only 1 hour and sometimes over 24 hours) the program stops printing to the console and in fact stops running altogether. I know it isn't simply that it stops printing to the console because the program also sends an email regularly, and after it stops the emails stop coming as well. It does not always say "build complete" or throw an exception, though sometimes it will simply say "build complete" and stop running.
I have tried looking around the web, but I cannot seem to find any conclusive answer. I saw somewhere that the TimerTask will stop running if it throws an unchecked excpetion, but since it does not always stop at the end of a TimerTask but rather at some random point in the middle of a task, I don't think that is what's happening.
Does anyone have any idea what is going wrong and how I can work around it?
Any pointers would be much appreciated.
Thanks,
Paul
EDIT: after I tried putting a logger into my timertask, the code errored out with the following exception:
java.io.IOException: Couldn't get lock for Logging.txt. This may very well be a separate problem because I have never used a logger. I read somewhere that this exception probably means I am missing some permissions to write to the file in java (not sure if that is the case or how to fix in Netbeans). If I fix the logger it and it's unrelated I will delete this edit
EDIT: I forgot to mention that the Broadcast function involves a lot of communication with various servers. I think the problem might be that the program simply gets stuck on a line and never completes. In this case I need to figure out a way to have the broadcast method timeout after a certain amount of time and try again.
EDIT: here is an example of my code:
public void RUN(){
exchanges.add(Bitstamp);
exchanges.add(BTCE);
exchanges.add(CampBX);
t.schedule(
new TimerTask()
{
public void run()
{
Broadcast(exchanges);
UseLogger.Log();
}
}, 0,15000);
}
public static void Broadcast(ArrayList<Exchange> exchanges){
for (int i=0; i<exchanges.size();i++){
exchanges.get(i).prepareGetUpdate();
}
System.out.println("************** TICKERS *****************");
try{
for (int i=0; i<exchanges.size();i++){
System.out.println(exchanges.get(i).getPrices());
}
tickerException=false;
} catch (Exception e){
tickerException=true;
}
System.out.println("");
System.out.println("************** BALANCES *****************");
try{
for (int i=0;i<exchanges.size();i++){
System.out.println("i: " + i);
System.out.println(exchanges.get(i).getBalance());
}
balanceException=false;
} catch (Exception e){
balanceException=true;
}
System.out.println("************ ORDERS *****************");
try{
for (int i=0; i< exchanges.size();i++){
exchanges.get(i).getOrders();
if (exchanges.get(i).exchangeName.contentEquals("BTCE")){
exchanges.get(i).Total_btc+=exchanges.get(i).btcInOrders;
exchanges.get(i).Total_usd+=exchanges.get(i).usdInOrders;
}
}
orderException=false;
} catch (Exception e){
orderException = true;
}
for (int i=0; i< exchanges.size();i++){
exchanges.get(i).getUpdate();
}
btcDiff = totalBTC-originalTotal;
btcNeutral=true;
}
Related
I'm working on an Android app that runs on remotely-sited, unattended devices. It has a Service to periodically retrieve settings from a fixed URL. It does this by daisy-chaining posts of a Runnable to a Handler obtained from a HandlerThread.getLooper(): it does an initial post() after creating the Handler in the Service's startup, and thereafter it does a postDelayed() at the end of each run through the Runnable.
This works "forever" on some devices in the project (fetching the settings successfully every 30 seconds for thousands of hours), but on other devices it stops working after a variable amount of time (hours to tens of hours) and thereafter never works again. I've even added code to monitor the Service's activity and restart the process by issuing a new post() if it's been more than 5 minutes since the last run, and that code kicks in when as intended when the process stalls, but still the Runnable no longer runs.
Some pared-down code snippets, and then further discussion of the problem/symptoms:
public class SettingsMonitor extends Service {
private HandlerThread mHandlerThread = new HandlerThread("SettingsMonitorHandler");
private Handler mSettingsMonitorHandler;
private long mLastTryMillis = 0;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mHandlerThread.start();
mSettingsMonitorHandler = new Handler(mHandlerThread.getLooper());
mSettingsMonitorHandler.post(checkSettings);
return START_STICKY;
}
final Runnable checkSettings = new Runnable()
{
#Override
public void run() {
Log.d(TAG, "checking latest settings");
mLastTryMillis = System.currentTimeMillis();
getSettingsFromUrl(SETTINGS_URL);
// queue up next check
mSettingsMonitorHandler.postDelayed(checkSettings, appSettings.getSettingsMonitorIntervalMillis());
}
};
public void restartCheckingIfStalled() {
long settingsMonitorIntervalMillis = appSettings.getSettingsMonitorIntervalMillis();
long maxStalledMillis = 10 * settingsMonitorIntervalMillis;
long millisSinceLastCheck = System.currentTimeMillis() - mLastTryMillis;
if (millisSinceLastCheck > maxStalledMillis) {
mSettingsMonitorHandler.removeCallbacksAndMessages(null);
Log.d(TAG, "checkSettings stalled -- restarting...");
mSettingsMonitorHandler.post(checkSettings);
}
}
}
The app logs extensive debug info, including every exception caught in local catch blocks (e.g., inside getSettingsFromUrl()) as well as any exception caught in a global app-level UncaughtExceptionHandler -- there are no exceptions being thrown by the app. There are log entries made at many points in getSettingsFromUrl(), as well as the first line of the Runnable, but at some point all of these log entries cease to appear, so I infer that the Runnable itself is no longer actually running.
I monitor the Service from elsewhere in the app and so I know that it is running throughout the lifetime of the app (even after the Runnable no longer runs); at the same time, I call restartCheckingIfStalled() and I do see the log entries indicating that the re-start is being requested, but apparently the post() it issues does not cause the Runnable to run again.
It's a bit difficult to quantify, but it appears that this problem is occurring on devices that are showing other signs of having network connection problems (some are on wi-fi, some are on sim cards). I don't really know what to make of that possible correlation, though.
I am mystified that this process goes off the rails without any sign of trouble -- no exception is thrown, and the last successful run through the Runnable and getSettingsFromUrl() look completely normal. I am looking for suggestions about ways to isolate, identify, and ultimately fix the problem, because I've exhausted a bunch of ideas/tests and I'm still no closer to understanding it.
#x-code: Ok, here's getSettingsFromUrl() -- I don't (explicitly) set a timeout (I'll go search now for whether there is any kind of default). How might lack of timeout relate to or explain the symptoms I'm describing?
private boolean getSettingsFromUrl(String settingsUrl) {
Log.d(TAG, "trying settings file: " + settingsUrl);
try {
URL url = new URL(settingsUrl);
Scanner scanner = new Scanner(url.openStream());
while (scanner.hasNextLine()) {
String s = scanner.nextLine().split(SETTINGS_FILE_COMMENT_CHAR)[0].trim(); // remove any comments and trim leading/trailing whitespace
if (s.length() > 0) { // skip blank lines
AdminRequest req = new AdminRequest(s);
if (req.isSetReq()) { // only apply SET requests, not GET (or other nonsense)
String reqType = req.getReqType();
if (settingsToApply.containsKey(reqType)) { // override earlier settings with later
settingsToApply.remove(reqType);
}
settingsToApply.put(reqType, req);
}
}
}
scanner.close();
return true;
}
catch (FileNotFoundException e) {
Log.d(TAG, "settings file not found at " + settingsUrl);
}
catch (Exception e) {
Log.d(TAG, "error checking settings: " + Log.getStackTraceString(e));
}
return false;
}
This may beg further questions (about whether/how I use this function's return value -- which I do; about what these AdminRequests are and what I'm doing with them in the settingsToApply HashMap, etc). I'm willing to continue providing more info if it seems likely to lead to insight, but it's not clear to me why, at a minimum, I don't see the first "checking latest settings" message at the top of checkSettings()... how would a problem (e.g., lack of a timeout in accessing the URL) affect subsequent calls to checkSettings()? Do all invocations of checkSettings() run on the same thread, and it's tied up waiting "forever" to access the URL? If that's the case, why is restartCheckingIfStalled() not also blocked? I do get the Log.d() messages from that.
Edited to show the changes I made to add timeouts, which solved the problem per the responses I received: in getSettingsFromUrl() change these two lines
URL url = new URL(settingsUrl);
Scanner scanner = new Scanner(url.openStream());
to these:
URL url = new URL(settingsUrl);
URLConnection cxn = url.openConnection();
cxn.setConnectTimeout(URL_CONNECT_TIMEOUT_MILLIS);
cxn.setReadTimeout(URL_READ_TIMEOUT_MILLIS);
Scanner scanner = new Scanner(cxn.getInputStream());
Do all invocations of checkSettings() run on the same thread
Yes.
If that's the case, why is restartCheckingIfStalled() not also blocked?
Because it runs on your app's main (ui) thread.
The advantage of running a HandlerThread in a Service is that each message or Runnable that you post to it is placed in a queue, so you don't have to write thread-safe code.
One disadvantage is that this kind of blocking can occur. As GreyBeardedGeek points out, you should set a timeout other than 0 on your URL connection.
I suspect that the default connectionTimeout is 0 (wait forever).
And if the connection blocks 'forever', your handler thread will block as well - your subsequent posts will have no effect.
You should probably set both the connection timeout and the read timeout.
My result
Expected result
public void run () {
try {
handlers.addElement (this);
broadcast("Welcome " + name);
while(handlers.size() != 2){
if(handlers.size() > 2){
this.out.writeUTF ("The Room is full!");
this.out.flush();
handlers.removeElement(this);
socket.close();
}
}
broadcast("No of Player: " + handlers.size());
for(int i = 0; i < handlers.size(); i++){
GameHandler player = (GameHandler) handlers.get(i);
broadcast("Player " + (i + 1) + ": " + player.name);
}
System.out.println("Game starts!");
startGame(4);
....
}
protected static void broadcast (String message) {
synchronized (handlers) {
Enumeration e = handlers.elements ();
while (e.hasMoreElements ()) {
GameHandler handler = (GameHandler) e.nextElement ();
try {
handler.out.writeUTF (message);
handler.out.flush ();
} catch (IOException ex) {
handler.stop ();
}
}
}
}
The problem is the difference between the expected result and my actual result. I have no idea why the broadcast before the while loop runs normally but others run twice
Your problem is that in your case, each of the thread is sending the broadcast. Either you need to have a "master" / "server" of games thread that does the "system announcements" broadcasting, -or- elect one of the client threads (maybe the "player 1" thread?) to send the announcements.
The problem is the difference between the expected result and my actual result. I have no idea why the broadcast before the while loop runs normally but others run twice
You really don't give enough details on your problem but I see these issues:
You talk about TCP and the code mentions sockets but you are processing a local elements collection. Unless you are talking to the same JVM over TCP (which is strange) the elements collection is going to start 2 players on each client. Is that really what you expect?
Even though you says elements is a Vector you still need to synchronize on it at the start of the run() method because you are performing multiple operations on it and there are race conditions. For example, if 3 handlers are added, they will all remove themselves and close their own sockets.
Vector really is an outdated collection. You should be using something else.
When the first thread adds itself to elements it then enters a spin loop waiting for the second person to join the game. Seems like a waste there. Some small Thread.sleep(...) would be appropriate.
If the room is full I suspect that the thread should return; from the run() method. Instead it continues on which I suspect is not good.
Hope something here helps.
Today I realized something that appeared weird to me: I noticed that when I just do
try {
doSomething();
} catch (Exception e) {
}
it isn't slower at all than if I just do
doSomething();
So I ran a test and wrote down some quick code to prove what I saw, the code basically just loops over a function called doSomething() lots of times, one time without and one time with try-catch surrounding it. So here's the code to it if you want to test it yourself:
public class Main {
private static final long LOOPS = 1000000L;
public static final void main(String[] args)
{
System.out.println("Loop without try catch: "+loopWithoutTryCatch(LOOPS));
System.out.println("Loop with try catch: "+loopWithTryCatch(LOOPS));
}
public static long loopWithoutTryCatch(long loops)
{
long startTime = System.currentTimeMillis();
for (long i = 0L; i < loops; i++)
{
doSomething();
}
return System.currentTimeMillis()-startTime;
}
public static long loopWithTryCatch(long loops)
{
long startTime = System.currentTimeMillis();
for (long i = 0L; i < loops; i++)
{
try {
doSomething();
} catch (Exception e) {
}
}
return System.currentTimeMillis()-startTime;
}
public static void doSomething()
{
for (int i = 0; i < 250; i++)
{
if (i % 3 == 0)
{
i++;
}
}
}
}
And I received the following output:
Loop without try catch: 375
Loop with try catch: 373
I was surprised so I tested it again and again, but I always got similar results, both ways it runs pretty much in the same time.
And now my question is: Why?
I dont really understand it, as far as I know try-catch writes the resources before usage in some kind of table to later - if any exception is thrown - be able to clean it up and reference to the values it had before the exception occured.
This should take at least some time, shouldn't it?
I thought it is maybe because I the random example I choose doesnt represent it properly, and in that specific case in which I tested it it doesnt slow down anything, but that seemed very unlikely to me.
Then I thought maybe it just takes such a tiny amount of time that it isnt noticable with that "few" amount of executions, so I ran the test program again with a total number of 10 million loopings, but what I found just prooved what I had already found: It takes pretty much the same time for both executions.
So is there any logical explanation for that this is the case or just a example-specific behaviour of try-catch?
Thanks for any clarification in advance.
The "slowness" in throw / catch blocks comes from the process of throwing and catching the exception, not in the process of setting up "traps" for them. When you throw an exception, JVM must
Create an instance of an exception
Prepare space for the stack trace
Populate the stack trace into the prepared space
"Unwind" the stack down to the correct place
Pass the control to your exception handler.
When none of that is happening, JVM simply sticks a note that an exception handler is available at this level on the stack, and continues executing the actual code.
Making the feature penalty-free was a very important goal for language designers: programmers should not be required to pay for things that they do not use. Otherwise, programmers would be tempted to skip exception handling or go back to the C ways of using status codes in order to save a few CPU cycles here and there, spelling the end to the exceptions as a feature.
The bytecode generated from code like yours follows this pattern
1: invoke method
2: goto 4
3: store exception in catch block variable
// would contain handling code if there was any
4: return // or whatever comes after the try-catch
Exception table
if an exception of the type in catch block happens from 1 to 3, goto 3
So basically all you have added with a try-catch is an extra goto if no exceptions occur. Otherwise, the JVM will lookup the exception in the exception table and match where it occurred. It will then prepare the Exception and goto whatever instruction index is specified. That whole operation is heavy.
I need to check how many events are detected within 2 seconds. I have the timer working and I have everything else working...but I ran into a problem: the loop only checks one time, per second and I can't seem to figure out how to fix that. I need it to check constantly during these two seconds to see how many events there were in total!
Here is what I have:
int seconds = 0;
System.out.println("Seconds: " + seconds);
while(seconds < 2)
{
//Wait 1 second
try {
Thread.sleep(1000);
}
catch(Exception e) {}
seconds++;
System.out.println("Seconds: " + seconds);
//This needs to be looping the whole time.
//But right now, it's being blocked and only checked once
if(eventDetected() && seconds <= 2){
events++;
}
}
So you can see my problem. I can't split them up because then the second timer would run, and THEN eventDetected() would be checked. I need it to check constantly DURING the two second timer...so I basically need both things to happen at once. Is there any way I can do this?
Thanks for any help ahead of time!
I think your design pattern needs work -- I don't know what type event you're looking to detect, but no matter how short your sleep time is, there's a chance you could miss an event using the current pattern. Here's what I suggest:
Have eventDetected() increment your events counter. That way, you won't miss an event.
Then, you just need a way to turn on and off listening (and perhaps resetting the event counter). If you're sure that in you're current pattern you are really in a different thread that won't block your eventDetected() method, you could set a flag to check. For example:
When you want to start listening:
listenForEvents = true;
In eventDetected():
if (listenForEvents) { events++; }
When you want to stop listening (for example, after your Thread.sleep() call):
listenForEvents = false;
With multithreading, make sure to watch out for concurrency issues checking and setting the variables, of course.
I would tell you what kind of event I have to keep track of but then I'd have to kill you :D
Answered my own question. Hopefully this will help anyone else out who has a similar problem at some point! I looked up multithreading a bit...
I created a new class EventTimer which implements Runnable, with a public field for seconds:
public class EventTimer implements Runnable{
int seconds;
static int timerThreadCount = 0;
Thread t;
public EventTimer() {
timerThreadCount++;
this.seconds = 0;
t = new Thread(this, "Event Timer");
t.start(); // Start the thread
}
#Override
public void run() {
// TODO Auto-generated method stub
while(seconds < 2)
{
//Wait 1 second
try {
Thread.sleep(1000);
}
catch(Exception e) {
System.out.println("Waiting interupted.");
}
seconds++;
System.out.println("Seconds: " + seconds);
}
}
}
Then I used an instance of the EventTimer, and used a while loop & if statement to solve my problem.
EventTimer t = new EventTimer();
while(t.seconds < 2){
if(eventDetected()) events++;
}
It was actually quite simple! I realize that each iteration of my loop of operation (since the entire code piece above is inside an infinite loop) will create a new EventTimer thread and I will eventually run into memory problems however. How would I close/end a thread after the timer has reached 2 seconds?
I was just wondering how i would let my java program continue running, but always be ready to take input.
Right now i am using a bufferreader and reading in a line, but that makes my program halt and wait for input. I want the program to continue running but be ready to take input whenever needed, is there a way to do this?
I would expect that you're going to have to look into multithreading your application in order to get this working as you desire.
Edit: Of course, while this functionality can be achieved by a purely CLI interface, you would probably be better off exploring other options (i.e. GUI options) if you intend on having a full response/event-driven system running in a multithreaded fashion.
Here is a quick example of how a multi-threaded command line interface application may work. This will not require polling for input, nor a GUI interface in order to perform tasks in the background while waiting for input from a user in a console.
In this example, a Thread is running in the background, which can be told to output a greeting in a specified number of seconds later.
public class CommandLineMultiThread
{
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
// Makes and runs the background thread.
MyThread myThread = new MyThread();
Thread t = new Thread(myThread);
t.start();
// Get the number of seconds to wait from the console.
// Exit when "0" is entered.
int waitDuration;
do
{
waitDuration = s.nextInt();
myThread.setGreetIn(waitDuration);
} while (waitDuration != 0);
myThread.quit();
}
static class MyThread implements Runnable
{
boolean running = true; // Boolean to keep thread alive.
long greetingTime = Long.MAX_VALUE; // Time to greet at.
public void setGreetIn(int i)
{
greetingTime = System.currentTimeMillis() + (i * 1000);
}
public void quit()
{
running = false;
}
public void run()
{
while (running)
{
if (System.currentTimeMillis() > greetingTime)
{
System.out.println("Hello!");
greetingTime = Long.MAX_VALUE;
}
try
{
Thread.sleep(100);
}
catch (InterruptedException e) {}
}
}
}
}
The Scanner class can be used to accept user input from the command line interface by routing the input from the System.in object.
Then, while the background thread myThread is running, the main thread is waiting for an input from System.in via the Scanner.nextInt method. Once the seconds to wait has been accepted, the background thread is told to wait until a certain time, and once that time arrives, the greeting Hello! is output to the console.
I think your program will have to occasionally poll for user input.
Give it a nice multi-threaded GUI instead of a CLI :)
I agree with James, another alternative is "faking" continuous program running. This won't work with all scenarios, but you can set a timer right before you display the user input, then calculate the time between stop and "start" again when the user inputs something.
Use that time to perform a repeated function a certain number of times. This is only helpful if you've got something on a timer itself already, like a constantly draining integer every few seconds.
An example:
You ask the user a question but only want to give them 5 seconds to answer. When the user answers (hits enter) the program will compute the time it took them to enter, if too long, throw one message, if under the time limit throw another.
I'm only suggesting this method because threading, which is what you really want to get into, is quite advanced.