How could I make a thread loop? - java

Every 3 seconds, I want the server to send a message.
To do this, I have this code.
try {
Thread.sleep(3500);
getPackets().sendGameMessage("[Server Message]: Remember to vote!");
} catch (InterruptedException e) {
e.printStackTrace();
}
The code works of course, waits 3 and a half seconds, sends the message.
But how can I make it loop, so every 3 and a half seconds, it will send it without stopping?

I'm a bit surprised that someone tackling networking in Java doesn't know how to put code in an infinite loop. Thus, I wonder if your real question is "is there a better way?"
To that question, I would say that you should consider using either java.util.Timer to send the message, or using scheduleAtFixedRate() from a ScheduledExecutorService obtained from Executors.newScheduledThreadPool().

The best way is to use a Timer. See Java how to write a timer

spawn the above code in a separate thread and enclose it within a while(true) loop.

This kind of code is not very useful because it blocks the current thread and also seems to unnecessarily clutter the program logic. It's better to delegate it to a worker thread that executes the send in the background. Also Thread.sleep is known to be inaccurate.
As of the latest Java versions, I think the most elegant way to do it is using ScheduledThreadPoolExecutor:
ScheduledThreadPoolExecutor executor = new ScheduledThraedPoolExecutor(1);
executor.scheduleWithFixedDelay(new Runnable() {
public void run() {
getPackets().sendGameMessage("[Server Message]: Remember to vote!");
}
}, 0, 3500, TimeUnit.MILLISECONDS);
Also you don't have to worry about that annoying InterruptedException.

Related

is it necessary to extend thread class to use the sleep method..? [duplicate]

This question already has answers here:
What is the difference between a static method and a non-static method?
(13 answers)
Closed 4 years ago.
So I'm learning java and I kinda got confused here...
So while learning threads I learned that it is necessary to extend Thread class or implement Runnable class.
And while going through this program Thread.sleep() is used without doing any of the above process.
link:
http://www.abihitechsolutions.com/applets-mini-project-in-java-free-source-code/
Can someone explain me what is going on?
By using Thread.sleep(X) actually you are pausing execution for time X.
This is suitable for sending requests to servers or database. Nobody wants to send a huge request to DB or server in one time.
Making small portions is always reasonable. You can divide your requests and send them by waiting specified time duration.
This is one of the important usages of Thread.sleep()
There is a much proper way to handle thread pausing which is wait/notify. I suggest using it.
You can check from there;
https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
It is much better to implement Runnable than to extends Thread. Thread.sleep() is a static method so you can call it from anywhere.
class RunMe implements Runnable {
#Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("Hello");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Bear in mind that all Java code runs in a thread so calling Thread.sleep() can be done anywhere.
The reason why you can use Thread.sleep without actually creating a thread is because the main program is also running on a thread. You're simply calling sleep on the main thread. When you call Thread.sleep, java will figure out for you which thread it is actually running on.

killing a java thread in test

I'm writing a sort of tutorial about programming (it will be a Java repo on github) where users can clone the repo and write their own code inside empty methods to solve algorithmic problems. After they write their code, they can launch unit tests to check if their solution is correct and if it completes execution in less than a certain time (to assure they found the most efficient solution).
So my repo will contain a lot of classes with empty methods and all the non-empty unit tests to check the code the users will write.
What I'm doing in the JUnit tests is something like that:
// Problem.solveProblem() can be a long running task
Thread runner = new Thread(() -> Problem.solveProblem(input));
runner.start();
try {
Thread.currentThread().sleep(500);
}
catch (InterruptedException e) {
e.printStackTrace();
}
if (runner.isAlive()) {
fail("Your algorithm is taking too long.");
runner.stop();
}
Now, if a user writes a not optimized algorithm, the test fails correctly, but the runner thread will continue to run (and so will do the test thread) until it terminates, which can happen after minutes, though I call running.stop(). So I have tests that can last minutes instead of seconds like I'd like.
I know how to gracefully kill a thread in Java, but in this case I don't want the users to take care of multithreading issues (like checking/updating shared variables): I just want them to write only the code to solve the problem.
So my question is: is there a way to abruptly kill a thread in Java? If not, is there any other approach I could follow to accomplish my goal?
Thanks,
Andrea
You can use a ScheduledExecutorService with a timeout:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
Future<?> future = executor.schedule(() -> Problem.solveProblem(input));
try {
future.get(500, TimeUnit.MILLISECONDS);
} catch (Exception e){
fail("Your algorithm is taking too long.");
future.cancel(true);
}
Will probably require some refinements but you get the basics.
Use Thread.currentThread().getThreadGroup() to iterate through. Thread.stop is the brute-force way, but in your case it'll probably work if you call Thread.interrupt -edit- I read this too quickly and thought you were calling sleep in your spawned threads. Rereading, I see that you are just doing this in your main thread, so as RealSkeptic commented on this post it is uncertain and probably unlikely that interrupt will solve the problem

Monitor thread status

So I have this very relevant thread I start when the program starts.
The thread is listening to events coming from a bigger system as the main thread does other stuff.
The thread should never stop working and if it does, it should be recreated and started.
I think I know multiple ways to achieve this, but I'd like to know your opinion on some things :
Am I just striving for nothing? I mean, if I ideally try-catch all the code that can go wrong, will the thread ever betray me for no obvious reason?
What's the best practice to do what I stated? Periodically check the thread health with another thread and a ScheduledExecutor? Implement some kind of observable-observer pattern?
You can create the ExecutorService which is listening to the events via Executors.newSingleThreadExecutor().
In that case You don't have to take a look at the thread if it is healthy, the ExecutorService takes care of that. The SingleThreadExecutor is responsible that only one Task (Runnable or Callable) is running at one time.
If you are checking using normal Java provided methods to view the thread state correctly, you should not have any errors. In the case that a checked exception is thrown or the thread exits for some weird reason, a try-finally block should be sufficient to start a new thread (also ensure it is non-daemon). You could use a while loop with a periodic pause, preferably using a thread scheduling mechanism such as timed wait(...), or timed LockSupport#park(...). You can also sleep the thread as well.
The thread should never stop working and if it does,...
OK, so write it so that it will never stop working.
public void run() {
while (true) {
try {
Message message = receiveNextMessage();
handleMessage(message);
} catch (Exception ex) {
LOGGER.error(ex);
if (somethingTrulyHorribleHasHappened(ex)) {
Runtime.getRuntime().exit(1);
} else {
maybeResetSomethingThatNeedsToBeReset();
}
}
}
}
This is a somewhat pointless and futile exercise. An app-lifetime thread should be debugged and made to not stop. The main thread of your app lasts for the process lifetime and any other threads should be designed, tested and debugged to the same standard.
What would happen if the thread that stopped had corrupted data in other threads when it crashed? If you just restarted it somehow, the data corruption may well make the situation worse.

Heisenbug: Thread doesn't run without a sysout [duplicate]

This question already has an answer here:
Loop doesn't see value changed by other thread without a print statement
(1 answer)
Closed 7 years ago.
I have experienced weird behaviour while coding a simple game. Basically, I create a thread with an infinite loop that fires an event in my game every couple of seconds. With the Sysout(runAnimation) in place everything works fine. However as soon as I remove it the even stops occurring.
It appears that the system.out calll is affecting the behavior of the program, does anyone have an idea why this could be happening
Here is the loop:
private void run(){
long lastTime = -1;
while(true){
int timePerStep = (int) Math.ceil(ANIM_TIME/frequency);
System.out.println(runAnimation);
if(runAnimation && System.currentTimeMillis() - lastTime > timePerStep){
lastTime = System.currentTimeMillis();
controller.step();
try {
Thread.sleep(timePerStep);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
It's started during the construction of my class as follows:
animThread = new Thread(new Runnable() {
#Override
public void run() {
GUIView.this.run();
}
});
animThread.start();
The System.out.println() call is synchronized (most PrintWriter method calls are) so I suspect that there is something that you are not synchronizing on inside of your code. I wonder about the runAnimation field. Could it be that it is set in another thread? Maybe it needs to be volatile? Any field that is modified in one thread and read in another needs to be synchronized or volatile. Reading the Java thread tutorial around synchronization may help.
Without seeing more of the code, it's hard to put a finger on it but I suspect this answer will help anyway.
Lastly, do you really want your thread to spin until runAnimation is true? That's a very bad practice. Maybe you should sleep for some time in the loop if runAnimation is false as well. Another idea is to use a CountDownLatch or other signaling mechanism to pause your thread until it needs to do the animation.
If your field is not volatile, the JIT can assume it doesn't change and place it in a register or even inline it in code. Placing a system call in this tight loop can
prevent the JIT from optimising the code this way as it cannot make assumptions about whether the thread modifies the field.
slow down the loop so it is not run 10,000 times (which is the point at which the JIT kicks in)
For more details, here is an article I wrote on the subject Java Memory Model and optimisation.

question related with java

Can you please suggest how to use until command in Java, actually I have to perform this System.exit(0); after 3 second of current system time. So I am thinking to do by long time=System.currentTimeMillis();
until(System.currentTimeMillis()<(time+3000))
{
System.exit(0);
}
But it reports an error
Actually java does not have an until command but you should use a while-loop or a do-while-loop instead.
Note: Thread.sleep(3000); would be a better way to sleep for three seconds.
I might have misunderstood your requirement but if you just want to wait for 3 seconds then call System.exit(0), you can just use:
Thread.sleep(3000);
System.exit(0);
I apologise if I have misunderstood your question.
If you're trying to wait for a specific period of time constantly polling on the elapsed system time is not the way to go. Alternatively you can use the thread scheduler to pause execution of the current thread and request that the JVM notify you when the time is up. This allows other threads in a multithreaded environment to get things done while you wait.
try {
Thread.sleep(3000);
} catch (InterruptedException ex) {
// Insert appropriate exception handling here...
}
Thread.sleep makes the currently executing thread move to the ready state for 3000ms. The JVM is then responsible for moving the thread back to the running state when at least 3 seconds is up.

Categories

Resources