Alongside the implicit User Interface thread, i have made two threads (runnables), both having a while loop inside them in which i periodically check for updates inside a message queue which I've implemented.
The problem at first was that the two while loops were infinite, and they changed so quickly and so much that they used up almost all the CPU of the device.
So i thought about making the while loops sleep for about 100 milisec after each cycle, to let the other threads do their work, but i came across another issue:
NOW, the problem is that the threads sleep for 100 milliseconds, but they don't let the UI thread work during that time :( And what this does is make the UI laggy. When i drag something on the screen it lags a bit.
So what i want to do is make these threads (these while loops) check the message queue flag every 100 miliseconds, but during those 100 miliseconds i want to let the UI thread run. How can this be accomplished?
EDIT 1
I found the yield method, which stops the running of the current thread, but when do i call this? I would need to call the sleep thread and at the same time make it yield somehow ... ??
EDIT 2
The two classes are singletons, and i start them from the first Activity of the application, so when the app starts (the UI thread)
//Obtain object of singleton classes
ControllerSingleton controller = ControllerSingleton.getControllerSingleton();
OpponentSingleton opponent = OpponentSingleton.getOpponentSingleton();
//Start threads
/*--------CONTROLLER----------*/
Thread t;
t = new Thread( controller );
t.setName("ControllerThread");
Log.i("Remy","Starting Controller thread...");
t.start();
/*--------OPPONENTS----------*/
t = new Thread( opponent );
t.setName("OpponentThread");
Log.i("Remy","Starting Opponent thread...");
t.start();
And inside each run() i have the next code:
public void run()
{
while( true )
{
//Check if any messages in the queue
if ( queueEmpty() == false )
{
//Do something ...
}
/*HERE IS WHERE I WOULD LIKE TO TELL THE THREAD TO STOP AND WAIT FOR 100 ms*/
}
}
I think that the thing you need to use is Handler. You might want to see this tutorial for example.
Related
To give some details about what I'm trying to do: I'm making a Minecraft plugin in Java. I have an Object which is bound to the Player object of Minecraft using a HashMap.
I have a method in this object which is something like:
public void faint() {
... //Apply the effect on the player
//wait for x seconds, and if the player didn't already wake up, wake them up. (player.wakeUp())
}
Obviously, there will be a lot of stuff going on, so I want this to happen asynchronously. The timer will go on in the background and it won't block anything else in the code.
Sorry if my question is too simple, but I really checked the web and I'm new to Java, so forgive my ignorance.
You can create a separate thread by implementing a Runnable interface like this and do the delay in there.
// This is happening in the main thread
Thread thread = new Thread(){
public void run(){
// This code will run async after you execute
// thead.start() below
Thread.sleep(1000)
System.out.println("Time to wake up");
}
}
thread.start();
Use the Bukkit scheduler.
Bukkit.getScheduler().runTaskLater(yourPluginInstance, () -> {
// put code here to run after the delay
}, delayInTicks);
When the code runs after the delay it will run on the main server thread.
I have 3 functions in a java program:
the first two are used for polling any SNMP device; all they do is get the inbound n outbound traffic.
the third function gets any value based on the input user enters.
The main function is menu driven. It asks users to enter choices as to what value they need and accordingly the value is returned using the third function.
While this goes on I want the first two functions to run every 5 seconds and it shouldn't mess with the menu driven program.
Any ideas on how to do that ?
p.s.: I tried a few exapmles but they reset the menu (do while loop) every time they are done with the first two functions.
Stab in the dark - would a Timer function calling a Task work?
For first two function you could use
while(true) {
thread1.start();
thread2.start();
Thread.sleep(5000);
}
For third thread you should make Deamon thread(by thread3.setDeamon(true)) which runs background. In the run method of every kind of thread(which don't forget to implements Runnable or extends Thread) you could make what work is thread doing. Good Luck!
You probably need to go the multithreading way because SNMP communication induce possibly long timeouts waiting for a reply, and you do not want the timeouts to freeze the interface (waiting on the UI thread would be bad).
To make it simple, one Thread could be used to communicate for the "two functions", polling alternatively function1() and function2() (can be extended later with a Thread Pool).
The main thread can be used for your main input (like normal java programs).
Snippet for threaded logic, where function1() and function2() are time-consuming (note: there is no sleep since cadencing would be done within the polling in your functions, if you need to reduce polling frequency, use wait(timeout) and notifyAll() -- necessary to quickly exit when the user clicks Exit menu) :
while ( ! isTerminated() )
{
function1();
if ( isTerminated() )
break;
function2();
}
I want to do some calculation, but if they took too much time(say 10 sec), I want to stop it and show current best result.
Is it ready way to do it in Java? I don't want to write time checking in every function.
Use Timer as suggested or go for multiple threads. In your main program, another thread with the calculation is started. The main thread sleeps via Thread.sleep and terminates the calculation after the timeout.
main thread +-------+---sleeping---termination----+
| |
another thread +---calculation---+
You could make a separate thread that you can start at the beginning of your calculation thread, and after 10 seconds with the Timer.sleep(int) method, set a boolean value to true. Then in the calculation thread, if(finished) break;
Have another thread with a loop that increments a value every second, and then exits at 10 seconds.
public class counter extends Thread, implements Runnable{
public void run()
{
for(int index=0; index<10; index++)//Waits ten seconds
{
this.sleep(1000);//ms
}
System.exit(0);//Closes the application
}
The main Thread can still execute, though. To cancel the shutdown I suppose you could have a volatile boolean that gets set to true if input was recieved in time.
I have written a Java ME puzzle game. I have written the code thus: there is a thread that starts when the app starts, and, once the game has got going, there's a second thread that just runs in an infinite loop -- the main game loop. The second thread looked like this, at one point:
public void run() {
init();
while (shouldIRun) {
updateGameState();
checkUserInput();
updateGameScreen(getGraphics());
this.flushGraphics();
}
}
Lovely. This thread just runs and runs, until I want to kill it, when I just set the boolean shouldIRun to false, whereupon it exits gracefully.
But later on I realised I wanted more. The game is a puzzle game and it's possible for the player to make the wrong moves and then get stuck. When this happens they can fire up a form and select the "restart level" option. A flag restartLevel then gets set, and when the infinite loop gets to the updateGameState() method the level is restarted. But this feels to me like a bit of a gamble -- I don't want to start changing variables of objects being used in the main loop in case of concurrency issues, although I'm probably being paranoid. In practice what I realised I wanted to do was very clear: I simply wanted to pause the infinite loop thread, change the variables to what I wanted, and then restart.
I have done this in the following way:
public void run() {
init();
while (shouldIRun) {
if (shouldIWait) {
iAmWaiting=true;
while (shouldIWait) { };
iAmWaiting=false;
}
updateGameState();
checkUserInput();
updateGameScreen(getGraphics());
this.flushGraphics();
}
}
What I am thinking is the following. If I now want to "pause" this second thread, from the "base" thread, I just set the shouldIWait variable to true, and then just loop until I notice the iAmWaiting variable is also true. I now know for sure that the second thread has paused and I know precisely where it has paused, where by "paused" I actually mean "is stuck in an infinite loop for the time being". I can now goof around with some essential variables, restart the level, and generally sort things out, and then finally set shouldIWait back to false and off we go again.
My question is this: this works fine, for me, but smacks of being a kludge. Is there some completely standard way of doing what is presumably a common thing -- pausing a thread at a given point and then restarting it when I'm ready, which is better than what I'm doing? In particular I suspect that "putting java into an infinite loop" is perhaps not a clever thing to do.
Normally, this is what you would use Object.wait() and Object.notify() for.
There are a couple of ways to implement it for your situation, but here's a simple example:
Object monitor = new Object();
volatile boolean done = false, wait = false;
/* Running on one thread: */
public void run() {
synchronized(monitor) {
while(!done) {
while(wait) {
monitor.wait();
}
gameLogicAndStuff();
}
}
}
/* Running on another thread: */
public void showResetForm() {
wait = true;
synchronized(monitor) {
actuallyShowResetForm();
wait = false;
monitor.notifyAll();
}
}
Maybe it would just be simpler to kill the thread and start a new one with the new level.
If there is some information that needs to be carried from one level to the next, maybe you could refactor your code such that you gather some general information first and then start a thread for each level. (And by starting a thread, I mean using a thread pool.)
I don't think what you are currently doing with busy waiting is evil. As Ben Flynn mentioned in the comments, you could make it semi-busy waiting by looping over Thread.sleep(50).
I'm writing a live wallpaper, and I'm forking off two separate threads in my main wallpaper service. One updates, and the other draws. I was under the impression that once you call thread.start(), it took care of everything for you, but after some trial and error, it seems that if I want my update and draw threads to keep running, I have to manually keep calling their run() methods? In other words, instead of calling start() on both threads and forgetting, I have to manually set up a delayed handler event that calls thread.run() on both the update and draw threads every 16 milliseconds. Is this the correct way of having a long running thread?
Also, to kill threads, I'm just setting them to be daemons, then nulling them out. Is this method ok? Most examples I see use some sort of join() / interrupt() in a while loop...I don't understand that one...
No
No
For #1, I believe your threads are terminating. Once the run() method is left, the thread is considered terminated. If you want the thread to run "forever", you need to repeat your actions.
For #2, the thread will continue running even if you lose all references to it. I would suggest a signal or condition to the worker thread, followed by a join() in the main thread.
Like Yann said, if you keep having to restart your thread(s), it means you are probably not looping correctly.
Say your wallpaper just has a ball moving around the screen, this would be a sample run() method:
boolean isAnimating;
public void run() {
isAnimating = true;
while(isAnimating) {
moveBall();
isAnimating = isWallpaperVisible(); // or whatever conditions apply to not keep animating
}
}
This way your run method will keep running indefinitely.