I want to wait 300ms after 2 lines run to run the same 2 lines again, without freezing the thread.
wait(300); and Thread.sleep(300);, along with some loop I found on SO (below) either freeze the thread, exit cleanly(?) or lag the thread by running the function a million times.
I want to wait 300 milliseconds and then run
mc.player.rotationPitch = 90;
mc.playerController.processRightClick(mc.player, mc.world, hand);
without freezing the thread, as sometimes it doesn't time properly if the thread is frozen, and it's annoying for the user if it's going to freeze every time.
I've tried wait, Thread.sleep, TimeUnit.MILLISECONDS.sleep and
long lastNanoTime = System.nanoTime();
long nowTime = System.nanoTime();
while(nowTime/1000000 - lastNanoTime /1000000 < 300 )
{
nowTime = System.nanoTime();
System.out.println("KAMI: Tried to pick up bucket");
}
I've already shown the relevant examples above.
Full code is here
Expected: thread works normally, and my 2 lines, (rotation pitch and right click) run 300 milliseconds after the previous rotation pitch and right click
Actual results: commented in code. Depending on the method used thread either lags, exits or crashes
You will need another thread to do this "without freezing" the current thread. This can be done quite easily, something like:
import java.lang.Thread;
public class Main {
public static abstract class After extends Thread {
private int sleep = 0;
public After(int sleep) {
this.sleep = sleep;
}
public void run() {
try {
Thread.sleep(this.sleep);
} catch(InterruptedException e) {
//do something with e
}
this.after();
}
public abstract void after();
}
public static void main(String[] args) {
After after = new After(300) {
public void after() {
//mc.player.rotationPitch = 90;
//mc.playerController.processRightClick(mc.player, mc.world, hand);
System.out.println("testing");
}
};
after.start(); //this will execute the code in 300 ms
//do what ever you want to do during the 300ms
after.join(); //join all threads at the end of your code
System.out.println("done");
}
}
Use After when you want to create a delay. Hope this helps!
Related
I 'm listening rs232Com using Portcom event-listener then generating propertychangelistener for interface controllers and everything works fine.
My new problem is that acquisitions for some sensors (anemometer) can terminate without any particular indication ( Pulse response ) and mostly dependent of bearings used.
The only solution i can see is that after an amount of time without anymore acquisition ( 2000ms ) i would like to end records to avoid recording data due to involuntary sensor handling .
At this point i can stop acquisitions unregistering controller of new message listener list using a button but i would like to do that automatically.
The point that miss me is to create a Timer that could launch a task after his delay timed out.This with a re-init function to feed him at each acquisition, barely the same way a watchdog works.
I started to search on web but i didn't find solutions and moreover which direction to go to
-Timer class
-Using a Thread / Runnable
-Schedule
-Modified watchdog
Thanks in advance
For this kind of problem, I often go with a custom thread that has a timer as attribute. The thread check its timer regularly and do something when it ends. And in my main I can add time to the timer attribute if I need to continue.
private static class CustomThread extends Thread {
private static int wait = 1000;
private int timer = 0;
public DeleteThread(int timer) {
this.timer = timer;
}
public void addToTimer(int time) {
this.timer += time;
}
public void run() {
while(this.timer > 0) {
try {
Thread.sleep(wait);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.timer -= wait;
}
//timer as ended
doSomething();
}
}
public class Main {
public static void main(String[] args) {
CustomThread myThread = new CustomThread(2000);
myThread.start();
//someCode
//Here I need my thread to continue for 1000 more
myThread.addToTimer(1000);
}
}
I want to generate random number after every 2 seconds in my java (Android) program continuously for at least 10 minutes. But I just want to pause/delay execution of code in only one method and not the whole program.
I tried using Thread like this -
boolean stop = false;
int random_number = 0;
while(true){
if(stop){ //if stop becomes true, then
return; //terminate the method
}
random_number = Math.random(); //generate random number
//which is used bu some other
//part of code
try {
Thread.sleep(2000); //delay the code for 2 secs
} catch(InterruptedException ex) { //and handle the exceptions
Thread.currentThread().interrupt();
}
}
However, this doesn't work as Thread.sleep stop the whole program execution instead on just stopping execution of code inside method and my whole screen becomes blank.
I also tried using Handler but it didn't work either as it doesn't stop execution of code in my method and instead just stack up.
This will demonstrate the working of it better -
while(true){
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
System.out.println("After 2 secs"); //this gets printed
//later
}
}, 2000);
System.out.println("Before 2 secs"); //this gets printed first
}
So the code stacks up making it equivalent to using while loop and make it incredibly slow.
Also, since I'm developing app for Android, I'm running on Java SE 6, so I can't use scheduleAtFixedRate. Is there any other way in which I can accomplish this?
Thanks a lot!
private Timer timer;
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//Generate number
}
}, 2000, 2000);
//Documentation (From SDK)
/**
* Schedule a task for repeated fixed-rate execution after a specific delay
* has passed.
*
* #param task
* the task to schedule.
* #param delay
* amount of time in milliseconds before first execution.
* #param period
* amount of time in milliseconds between subsequent executions.
public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
if (delay < 0 || period <= 0) {
throw new IllegalArgumentException();
}
scheduleImpl(task, delay, period, true);
}
and when you want to stop it
timer.cancel()
Option 1: Using threads, you might run your job off the main (UI) thread:
new Thread(new Runnable() {
// some code here ...
// This might be in a loop.
try {
Thread.sleep(2000);
} catch(InterruptedException ex) {
// Handle ...
}
}
}).start();
Then, if this new thread you'd like to modify UI (i.e. show/hide button, display something on the screen etc), remember to pass that through the UI thread, as only this one can modify the UI. You might consider using Activity.runOnUiThread() for that.
Option 2: Another, more Android-style way of approaching that issue is to use AsyncTask. It contains three callbacks which can be used to do work on- and off- the UI thread. Sketch of such a code could look like:
private class MyTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... param) {
// This method is running off the UI thread.
// Safe to stop execution here.
return null;
}
protected void onProgressUpdate(Void... progress) {
// This methid is running on the UI thread.
// Do not stop thread here, but safe to modify the UI.
}
protected void onPostExecute(Long result) {
// Also on UI thread, executed once doInBackground()
// finishes.
}
}
Option 3: Then there is also a Timer, as suggested by #Stultuske. It's less flexible then AsyncTask, but handles the interval for you.
Depending on your needs, you can still accomplish what you seek with Handler.
You don't have to create/start the Handler in a while loop(which, as you noticed, just stacks up unless you stop the loop itself, but it is a nonsense).
Just create the Handler and tell him to post delayed your Runnable instance. In the Runnable at the very end you check your conditions. If it is still OK, then post another runnable delayed, else you do nothing and the Handler will have no more executions.
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
System.out.println("After 2 secs");
random_number = Math.random();
if (!stop) // should not be stopped, so we add another runnable;
{
handler.postDelayed(this, 2000);
}
}
handler.postDelayed(runnable, 2000);
The only downside is that Handler could freeze if the device is not used for a while, meaning it will start the counting back from where it left once the device screen is turned on.
It could do like 1 minute of correct work, then block at 1.4 seconds when the device is gone in sleep mode, and once it is turned on again, Handler would do the remaining 0.6 seconds.
Still, not knowing your needs you may be unaffected by this behavior and the answer may fit you.
if you want to use thread, do it like this :
Thread t = new Thread(){
public void run(){
while(true){
if(stop) break;
random_number = Math.random();
sleep(2000);
}
}
};
t.start();
currently, i'm trying to write a programm, which should execute a seperate Java-program multiple times, but with different parameters. This executed Java-program calls a Thread-Class. Within this class, a connection to a (Game)Server is established. Once connected, the Threads sends a command to turn the connected player around every 10 milliseconds. I have 2 "solutions" for this:
The easy (working) one:
public class GeneralAgentTest {
public static void main(String [] args){
Thread thread = new Thread(new HexagonRunner("127.0.0.1",6000,"UnitedTestors",-30,-15));
thread.start();
}
}
This is working correctly, but not actually my goal. I need to start several of this Threads (new Thread(new HexagonRunner("127.0.0.1",6000,"UnitedTestors",-30,-15)); ) and each of this threads must be handled by a seperate process.
To do this, i wrote some code with an ProcessBuilder. This is within one class.
Second not correctly working one:
public void execute(Class class1, int a, String str, String team, String x,
String y) {
ProcessBuilder builder;
String javaHome = System.getProperty("java.home");
String javaBin = javaHome + File.separator + "bin" + File.separator
+ "java";
String classpath = System.getProperty("java.class.path");
String className = class1.getCanonicalName();
builder = new ProcessBuilder(javaBin, "-cp", classpath,
className, ip, port, team, str, x, y);
try {
process[a] = builder.start();
} catch (Exception e) {
e.printStackTrace();
System.out.println("failed");
}
public void loadPlayers() {
process = new Process[4];
for (int i = 0; i < 4; i++) {
try {
execute(processes.StartProcesses.class, i,
playerCombo[i].getSelectedItem().toString(),
playerTeam[i].getText(), playerStartX[i].getText(),
playerStartY[i].getText());
} catch (Exception e) {
System.out.println("Failed to create processes for players");
e.printStackTrace();
}
}
}
These are the functions i wrote, to execute the class(es) who is/are starting the thread(s).
Following class is executed:
public class StartProcesses{
public static void main(String[] args) {
Thread t = null;
t = new Thread(new HexagonRunner("127.0.0.1",6000,"UnitedTestors",-30,-15));
t.start();
JOptionPane.showMessageDialog(null, "should've started");
}
}
In my second try, the parameters which are given to the StartProcesses Class are containing some information like IP-Adresses, Portnumbers, Playerpositons and stuff like this. Anyway i was trying to execute the class with "hard" information, just to be sure it is working like in my first codepart.
The connections to the server are correctly established in both attempts, but in the first one the thread keeps working. In my second try it seems like the thread is dead after the connection is established. The process is still alive, since the connection to the server is still there.
This is a bit of code, but what i want to tell, is that the Thread is working correctly when executed manually, but it is not working correctly if i try to start the class automatically with the use of ProcessBuilders.
I really really hope you guys could understand what i am trying to say. Hopefully someone has a working solution for me.
Cheers.
EDIT: Add Code for HexagonRunner:
public class HexagonRunner extends GeneralAgent {
// Bunch of Methods
// Important Method:
#Override
protected void simulationCycle() {
turnAgent(40);
}
}
The simulationCycle() method, is the method that is going to be go through over and over again.
Since the class HexagonRunner is inherited from the class GeneralAgent, i'm going to post the relevant stuff of this class here as well:
public class GeneralAgent implements Runnable, UdpListener{
// Attributes, getters, setters, methods..
#Override
public final void run() {
// giving the worker threads the signal to start
mServerConnection.start();
mParser.start();
// waiting for the first information to be parsed, so that the
// simulation loop can run
try{
System.out.println("GeneralAgent-Run: waiting for latch");
mLogger.info("Run method: waiting for CountDownLatch");
mFirstDone.await();
}
catch(InterruptedException e){
System.out.println("GeneralAgent-Run: InterruptedException");
mLogger.info("Run method error: " + e.getMessage());
}
mLogger.info("Run method: CountDownLatch now 0, continue");
// setting the initial position
moveToPostion(mXStartCoord, mYStartCoord);
// the simulation loop
while (true){
simulationCycle();
// Shutdown if the game is over
if (mGameworld.getTime() >= 6000){ // later 6000+
System.out.println("Yeah, 50 runs completed -> Shutdown");
mLogger.info("General Agent - Time > 50, programm should terminate");
shutdown();
break;
}
// waiting for the threads to signal that they are
// ready (e.g. have new server information)
// for another round of the simulation loop
mPhaser.arriveAndAwaitAdvance();
}
}
I hope things get clearer now. I still have no idea where my code fails.
You could build somethin a lot simpler by using Executors. It' part of the comcurrent package introduced in Java 1.5. It basically works as follows:
// create a pool with 10 threads
ExecutorService executorService = Executors.newFixedThreadPool(10);
//loop as long as you need to detach your threads
for (int i = 0; i < 4; i++) {
// this actually contains the thread bit, will be executed in parallel
executorService.execute(new Runnable() {
public void run() {
// this is where your code is
new HexagonRunner("127.0.0.1",6000,"UnitedTestors",-30,-15)
}
});
}
// clean up when you're done to prevent leaks
executorService.shutdown();
That's it, much simple and you don't need to spawn different JVMs through ProcessBuilder, which is a lot slower.
I have a process which should react on some events. So when playFromList() is called it plays some sound from soundpool. Then in a thread I set a flag and for 3,5 seconds it should not play any sounds.
What I got is: It plays sound and if than wait 3,5 seconds. If playFromList() is called 5 times in 3,5 seconds it still gets to SoundManager.playSound(listNr), and still is done in 17,5 seconds. And its not exactly what I wanted. I wanted method SoundManager.playSound(listNr) called only once.
public class Settings{
public static boolean flag = false;
}
public class Main{
public void playFromList(int listNr,int g){
if(!Settings.flag){
SoundManager.playSound(listNr);
if(g ==0){
mpVolume((float) 0.3);
t5sec.run();
}else{pauseMus();}
}
}
private Handler vijfSeconden = new Handler(){
public void handleMessage(Message msg){
mpVolume((float)0.8);
}
};
Thread t5sec = new Thread(){
public void run(){
if(Settings.flag == false){
Settings.flag = true;
try {
Thread.sleep(3500);
} catch (InterruptedException e) {
Settings.flag = false;
e.printStackTrace();
}
vijfSeconden.sendEmptyMessage(0);
Settings.flag = false;
}
}
};
}
There are few problems with the code. Probably most important thing that is strange is
t5sec.run(), in Java you you should use start method on the Thread object to start new Thread. As written it will execute in the calling thread.
Second problem is absolute lack of synchronization, one way to fix that, I guess, would be to use AtomicBoolean instead of boolean in Settings.flag
Another issue is that it is quite expensive to start new thread every time. It is a bit hard to tell from the description precisely what you want to do, but if my understanding is correct you should just do something like this:
if ( (System.currentTimeInMillis() - lastTimePlayed) < 3500) {
playSound();
lastTimePlayed = System.currentTimeInMillis();
}
that's it and no threads required. You might want to use AtomicInteger to hold lastTimePlayed value if you want your class to be thread safe.
I was advised to use this code to make my method execute after a definite period of time, i modified it a bit and now I have:
private Handler mHandler = new Handler();
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
final long start = mStartTime;
// Get the difference in ms
long millis = SystemClock.uptimeMillis() - start;
// Format to hours/minutes/seconds
int mTimeInSec = (int) (millis / 1000);
// Do your thing
Location location = tracker.getLastKnownLocation(best);
RetrieveAvgPower(location);
// Update at the next second
mHandler.postAtTime(this, 1000);//start + ((mTimeInSec + 10) * 1000));
}
};
And I try to start and stop it with:
public void onClick(View v) {
switch (v.getId()) {
case R.id.start:
mStartTime = System.currentTimeMillis();
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 1000);
break;
case R.id.stop:
mHandler.removeCallbacks(mUpdateTimeTask);
break;}}
However, there is an issue. First of all, my method sets text and writes a line to log file, but if I use the code above text is not being set, however all info is being written to log file automatically. Another thing is i can't stop runnable - after it starts executing program seems to be not responding and crashes if I try to press stop button. What am I doing wrong and how it can be solved?
Shouldn't the last line of run() call Handler.postDelayed() rather than Handler.postAtTime()?
Depending on how event queues are implemented in Android you might be killing the thread by using the wrong one... you're basically repeatedly setting a Runnable to run at 1 second after the thread originally started, so no other events get to run.
To stop your runnable you can just add something like this:
class A implements Runnable
{
private volatile boolean runTask = false;
public void run()
{
runTask = true;
while(runTask)
{
// Do your thing
Thread.sleep(1000); // wait 1 second before "Do your thing" again
}
}
public void stop()
{
runTask = false;
}
}
As for the text not updating I didnt understand very well, is it in a swing gui that is not setting?
EDIT
Added a Thread.sleep(1000) at the end of the run method
EDIT by peer:
Moved the Thread.Sleep(1000) so that the Runnable will run once a second until stopped (instead of running continuously and then waiting 1 second after being stopped).