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);
}
}
Related
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!
My problem is that I cannot figure out a way of having a thread that "on the click of a button starts, and stops on the click of another button", and then if I click the same start button a NEW thread starts that does exactly the same operation as the first. So basically just a new instance.
In my program I have a Server app that has 2 buttons and 2 text fields. After the user has entered the correct username and password the Server app opens a new ServerSocket that listens for clients that want to connect. This is done in a separate Thread to prevent the GUI from freezing. After the stop button is pressed the Thread is stopped.
How can I get my program to start a new Thread, that does the same as the first one, when I press the start button again in the GUI? Must I perhaps make use of a loop?
Server App Code:
public class Server extends JFrame implements ActionListener {
JLabel instructionsLabel;
JLabel passwordLabel;
JPasswordField passwordTF;
JButton shutdownButton;
JButton startupButton;
JLabel usernameLabel;
JTextField usernameTF;
Thread MyThread = new Thread(new ServerRunnable());
public Server() {
super("Server");
initComponents();
}
// My problem is here
public void starterMeth() {
MyThread.start();
}
public void stopMeth() {
MyThread.interrupt();
}
// in these 2 methods
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
String f = "n";
ConnectionBean cb = new ConnectionBean();
char[] a = passwordTF.getPassword();
String b = new String(a);
String inputDetails = usernameTF.getText() + b;
Iterator it = cb.getDetails().iterator();
while (it.hasNext()) {
Object next = it.next();
if (inputDetails.equals(next)) {
f = "y";
if (source == startupButton) {
if (!MyThread.isInterrupted()) {
starterMeth();
JOptionPane.showMessageDialog(null,
"Congratulations! Server started.",
"Start-up Message",
JOptionPane.INFORMATION_MESSAGE);
} else {
JOptionPane.showMessageDialog(null,
"Please restart the server application.",
"Start-up Message",
JOptionPane.INFORMATION_MESSAGE);
}
} else if (source == shutdownButton) {
stopMeth();
JOptionPane.showMessageDialog(null,
"Server shut-down successfully!",
"Shut-down Message",
JOptionPane.INFORMATION_MESSAGE);
}
// only resets the text fields when the correct details are entered
passwordTF.setText("");
usernameTF.setText("");
}
}
if (f.equals("n")) {
JOptionPane.showMessageDialog(null, "Invalid username or password.", "Alert", JOptionPane.WARNING_MESSAGE);
}
cb.setCloseConnection(true);
}
private void initComponents() {
}
}
My Runnable Code:
public class ServerRunnable implements Runnable {
#Override
public void run() {
try {
ServerSocket ss = new ServerSocket(7777);
while(true) {
Socket cs = ss.accept();
new ClientThread(cs).start();
}
} catch (IOException ex) {
}
}
}
Overview
Although the creation of a thread is valid in Java, it is highly discouraged for numerous reasons. The most significant one is that the creation of a thread is quite costly and resource intensive. In addition, there are much safer/efficient models implemented in the standard library that could be used to simplify the issue. In this particular scenario, I would advise against this implementation because of the nature of the operation; start-stop reoccurring. Note, a thread cannot be restarted once it has been started and the only way to stop a thread while executing is to call interrupt(). Unfortunately, interrupting a thread requires the developer to implement error handling in the run() method. Below we will see the run() method of a Runnable or a Thread implementation.
public void run() {
try {
// Your connection logic would be here
yourLogic();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // Maintain status
}
}
Lets assume you made your own thread implementation called MyThreadImpl. Below we will see how to utilize it:
public void starterMeth() {
Thread myThread = new MyThreadImpl(); // Create thread
myThread.start(); // Start execution in parallel
}
public void stopMeth() {
myThread.interrupt(); // Stop the thread
}
Alternatively if you implement your own Runnable like you are in this application, it would look like this:
public void starterMeth() {
Thread myThread = new Thread(new ServerRunnable()); // Create thread
myThread.start(); // Start execution in parallel
}
public void stopMeth() {
myThread.interrupt(); // Stop the thread
}
Although both of theses are valid, there are better approaches.
A better approach
My suggestion is to utilize the CompletableFuture class due to its robust implementation and desirable control. CompletableFutures utilize the global ForkJoinPool.common() for its threading so that the application can execute with more efficiency. In addition, you can receive the Future that is within the object for later use instead of attempting to re-create it each time. Lets investigate how this implementation would work below:
public class Server {
CompletableFuture<Void> myFuture;
...
public void starterMeth() {
myFuture = new CompletableFuture<Void>(); // Create future
myFuture.runAsync(new ServerRunnable()); // Start execution in parallel
}
public void stopMeth() {
myFuture.cancel(true); // Stop the future
}
...
}
Java does not allow to restart a Thread once it has finished executing.
Interrupting the Thread you created will simply finish its execution. The problem here is that you are using the same Thread that has finished executing (once the stop button has been clicked).
I suggest one of the following:
Improve your runnable so that when the user attempts to clicks the shutdownButton button, it stops what it was doing, and acquires some sort of semaphore to make it "sleep" until the startupButton is hit again.
(Easier) Always create a new thread on starterMeth. Don't forget to check if a Thread is running and interrupt it before starting a new thread.
I hope this helps.
I want to delay doing something, along the lines of setting a countdown timer that will "do a thing" after a certain amount of time.
I want the rest of my program to keep running while I wait, so I tried making my own Thread that contained a one-minute delay:
public class Scratch {
private static boolean outOfTime = false;
public static void main(String[] args) {
Thread countdown = new Thread() {
#Override
public void run() {
try {
// wait a while
System.out.println("Starting one-minute countdown now...");
Thread.sleep(60 * 1000);
// do the thing
outOfTime = true;
System.out.println("Out of time!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
countdown.start();
while (!outOfTime) {
try {
Thread.sleep(1000);
System.out.println("do other stuff here");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
While this worked, more-or-less, it seemed like there should be a better way of doing this.
After some searching, I found a bunch of questions like these but they don't really address what I'm trying to do:
How do I schedule a task to run at periodic intervals?
How i can run my TimerTask everyday 2 PM
How to run certain task every day at a particular time using ScheduledExecutorService?
Java execute task with a number of retries and a timeout
I don't need anything this complicated; I just want to do a single thing after a certain amount of time while letting the rest of the program still run.
How should I go about scheduling a one-time task to "do a thing"?
While the java.util.Timer used to be a good way to schedule future tasks, it is now preferable1 to instead use the classes in the java.util.concurrent package.
There is a ScheduledExecutorService that is designed specifically to run a command after a delay (or to execute them periodically, but that's not relevant to this question).
It has a schedule(Runnable, long, TimeUnit) method that
Creates and executes a one-shot action that becomes enabled after the given delay.
Using a ScheduledExecutorService you could re-write your program like this:
import java.util.concurrent.*;
public class Scratch {
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public static void main(String[] args) {
System.out.println("Starting one-minute countdown now...");
ScheduledFuture<?> countdown = scheduler.schedule(new Runnable() {
#Override
public void run() {
// do the thing
System.out.println("Out of time!");
}}, 1, TimeUnit.MINUTES);
while (!countdown.isDone()) {
try {
Thread.sleep(1000);
System.out.println("do other stuff here");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
scheduler.shutdown();
}
}
One of the nice things you get by doing things this way is the ScheduledFuture<?> object you get back from calling schedule().
This allows you to get rid of the extra boolean variable, and just check directly whether the job has run.
You can also cancel the scheduled task if you don't want to wait anymore by calling its cancel() method.
1See Java Timer vs ExecutorService? for reasons to avoid using a Timer in favor of an ExecutorService.
Thanks it worked for me. I used scheduler to schedule a task at a batchinterval calculated at runtime.
manualTriggerBatchJob.setSchedulingProperties(pblId, batchInterval);
ScheduledExecutorService scheduledExecutorService =
Executors.newScheduledThreadPool(5);
#SuppressWarnings("unchecked")
ScheduledFuture scheduledFuture =
scheduledExecutorService.schedule(manualTriggerBatchJob,
batchIntervalInMin,TimeUnit.MILLISECONDS);
When I show an alertdialog, I start a thread that starts a 30 second countdown to update a determinate progressbar shown in this alertdialog.
I create the runnable as a static inner class so that I don't leak the context(activity), but then of course I can't access the flag to stop the thread, nor the views I want to update. How can I get around this?
public class MyDialogFragment implements DialogInterface.onShowListener, DialogInterface.onDismissListener {
private boolean stopThread = false;
private Progressbar countdownBar;
private TextView countdownRatio;
#Override public void onShow() {
Thread progressThread = new Thread(new myRunnable());
progressThread.start();
}
#Override public void onDismiss() {
stopThread = true;
this.dismiss();
}
private static class myRunnable implements Runnable {
int progressStatus = 0;
int numSeconds = 30;
#Override public void run() {
while (!threadStop && progressStatus < numSeconds) {
progressStatus++;
handler.post(new Runnable() {
public void run() {
countdownBar.setProgress(progressStatus);
countdownRatio.setText(progressStatus + "/" + numSeconds + " secs");
}
});
try {
// update the counter every sec
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
First - don't use Thread - you're asking for troubles, especially that you don't seem to be comfortable with multi-threaded programming. It's a tricky topic with tons of pitfalls. It's definitely not for noobs.
You may use AsyncTask for this - it has nice integration with UI event loop via AsyncTask.onProgressUpdate(). AsyncTask uses internal thread pool.
http://developer.android.com/guide/components/processes-and-threads.html#Threads
AsyncTask is ok for most trivial stuff. For more advanced uses try using Service with worker threads and message bus to communicate with fragments or activities. There is plenty of libraries for asynchronous programming. I can recommend this one:
https://github.com/stephanenicolas/robospice
It's main purpose if networking, but you can use it for other stuff as well.
Third solution is Loader API:
http://developer.android.com/reference/android/content/Loader.html
It's intended for asynchronous loading of data from database (SQLite is slow), but it's quite easy to use it for other stuff, such as data processing.
Remember: if you use Thread, there are 2 possibilities:
You are expert and you know what you're doing
You are green and you're doing it wrong
I've created a timer class and am testing it with junit4. The timer is notifies another class of the time which then activates a method. While testing I am unable to check what values are sent to the observer because the compiler gets stuck in the always loop used for the timer. Here's the test and the start code for the timer.
public void testSimpleTimerAsThread() throws InterruptedException
{
SimpleTimer st = new SimpleTimer(1000);
st.start();
Thread.sleep(250); // So we are 1/4th a second different
for (int x=0;x<5;x++)
{
assertEquals(x, st.getRound()); // assumes round starts at
Thread.sleep(1000); // wait for the next time change
}
}
public void start()
{
while (flag)
{
timeChanged();
try
{
// Sleep for var seconds.
Thread.sleep(1000);
}
catch (InterruptedException e)
{
}
}
}
Thanks for the help.
In the SimpleTimer class you should be overriding the run() method, not start().
Assuming SimpleTimer extends Thread, you have overridden the method in Thread that actually creates and launches the thread, so no new thread is being created and your thread code is being executed in the main thread when you invoke start(), which is why it hangs.