I am currently working on a MMORPG game and have a FixedThreadPool which contains 4-8(depending on hardware) runnable objects which handle the movements in game.
Here is the run method of the Runnable.
#Override
public void run() {
while(serverRunning){
synchronized (movementQueue) {
movementQueue.stream()
.parallel()
.filter((player) -> player != null && player.hasMovement())
.forEach((player) -> player.move());
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
These runnable will run as long as the server is running. Now there are many places I read that ThreadPools should only be used when the tasks are no longer than few seconds, but nowhere they explain what is the reason behind it.
If so what is the reason? I am new to java and trying to learn better ways to do a solution hence let me know if there is any other better way to do it.
Related
This question already has answers here:
How to properly stop the Thread in Java?
(9 answers)
How to timeout a thread
(17 answers)
Closed 2 years ago.
so I am making a java code testing web application and I am running each code execution in a seperate thread. The problem is that sometimes tests have a time limit or the student just writes an infinite while loop. I've tried to terminate my testing thread with "best practices" such as using interrupts but I have no control over the inner workings of my compilation function so I can't just tell the thread to look if it has been interrupted or not. I'd like advice on how to handle this situation better.
Here is my bare bones example of what I want to achieve:
public class Main {
public static void main(String[] args) {
CodeExecutionThread cex = new CodeExecutionThread();
cex.start();
try {
cex.join(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Thread should stop at this point.");
}
}
class CodeExecutionThread extends Thread {
public CodeExecutionThread() {
}
#Override
public void run() {
infinite_operation();
}
public void infinite_operation() {
while(true) {
System.out.println("thread active");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
I came accross the same problem more than once.
Probably not what you are looking for, but there is probably no better way than to use a flag inside the worker thread -- as described here for example: https://www.baeldung.com/java-thread-stop
When using a flag, there is of course a contract between the main thread and the worker -- you need to divide the infinite_operation into smaller chunks and check for the flag.
If you do not want that kind of contract or if it is not possible, consider using a process, which can be "safely" killed by OS (https://www.baeldung.com/java-process-api).
Consider this code:
class Solver {
private boolean abort = false;
public void solve(List<Case> cases) {
while(!abort) {
for(Case c : cases)
compute(c); // method that take too long to finish
}
}
// a bunch of methods
public void abort() {
abort = true;
}
}
// in another class
Solver solver = new Solver();
solver.solve(cases);
public void onSolveAborted() {
solver.abort();
}
How can I change this solution so I can abort the solve function instantly. I know I can implements the Runnable interface in Solver class so I can stop the thread. This will introduce many changes in our code and I don't know if the framework we are using allow creating threads.
This will not be possible without the use of threads. Something has to set abort() before the running thread will stop. Take a look at this example:
class Solver implements Runnable {
private List<Case> cases;
public Solver(List<Case> cases) {
this.cases = cases;
}
private void compute(Case c) {
try {
// Do some computation here
} finally {
// Sound the horns! Abandon ship!
}
}
public void solve(List<Object> cases) {
for (Case c : cases) {
try {
compute(c); // method that take too long to finish
} catch (InterruptedException e) {
// Hmm, maybe I should take the hint...
break;
}
}
}
public void run() {
solve(cases);
}
public static void main(String args[]) {
List<Case> cases = new ArrayList<Case>();
// Populate cases
Thread t = new Thread(new Solver(cases));
t.run();
do {
// Wait 30 seconds
t.join(30 * 1000);
// Not done yet? Lets drop a hint..
if(t.isAlive()) {
t.interrupt();
}
} while (t.isAlive());
}
}
Very simply, it launches solve in a thread. The main thread waits up to 30 seconds then interrupts solve method. The solve method catches the interruption and gracefully exits the computation. Unlike your solution using boolean abort, this launches an InterruptedException from anywhere in your thead code (and you should deal with the exception accordingly!) allowing you to halt execution at any time.
If you want more control, you can add the try.. catch inside compute so you can have a finally clause to close any opened files or whatnot. Perhaps better still, have a try.. finally in compute to deal with closing things in a "nice" way and the try.. catch (InterruptedException) in the solve method to handle what happens in the case of interruption (in short, cleanup logic and interruption logic don't have to be in the same method).
Do somthing like this
Let say, you have 100 cases, 10 has been solved and you want to abort remaing 90.
In your code, you are solving all the cases in one iteration, after that while loop check for abort.
public void solve(List<Case> cases) {
Iterator<Case> iterator = cases.iterator();
while (iterator.hasNext() && !abort) {
Case c=iterator.iterator.next();
compute(c);
}
}
Change your class to Runnable and use ExecutorService to run it. Then you can just use methods "shutDown()" or "shutDownNow()" methods. This is cleaner and less intrusive then what you suggested in your own question. Plus killing thread manually is a REALLY BAD idea. At some point in JDK itself in thread method "kill()" was killed as there is no clean way to do so properly
I have a Thread that only has to work when a certain circumstance comes in. Otherwise it just iterates over an empty infinite loop:
public void run() {
while(true) {
if(ball != null) {
// do some Calculations
}
}
}
Does it affect the performance when the loop actually does nothing but it has to check if it has to do the calculation every iteration?
Only creating a this Thread when needed is not an option for me, because my class which implements Runnable is a visual object which has be shown all the time.
edit: so is the following a good solution? Or is it better to use a different method (concerning performance)?
private final Object standBy = new Object();
public void run() {
while(true) {
synchronized (standBy) {
while(ball != null) // should I use while or if here?
try{ standBy.wait() }
catch (InterruptedException ie) {}
}
if(ball != null) {
// do some Calculations
}
}
public void handleCollision(Ball b) {
// some more code..
ball = b;
synchronized (standBy) {
standBy.notify();
}
}
You might want to consider putting the thread to sleep and only waking it up only when your 'ball' variable becomes true. There are multiple ways of doing this, from using the very low level, wait and notify statements to using the java.util.concurrent classes which provide a less error prone way of doing this. Have a look at the documentation for the condition interface. A data structure like a BlockingQueue would also be a solution.
Yes it does. This is the most simple implementation of busy waiting, and should be avoided whenever possible. Use wait/notify or java.util.concurrent mechanisms. Maybe you should be more specific about what exactly you want to achieve to get more useful responses.
Yes, it will certainly affect performance. To increase performance, you can consider putting in a bit of a time delay (say 500ms or 1000ms or even higher) in your code depending how crucial timing is to you.
Share a BlockingQueue between your threads.
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Object x) { ... }
}
I found the following interesting thing. In task manager, running that infinite loop like that, would consume 17% of my CPU. Now, if I added a simple
Thread.sleep(1)
inside the loop, which is only one milisecond, the CPU use dropped to almost zero as if I was not using the program, and the response time of the program was still pretty good on average (in my case it needed to reply things fast)
I wanted a little confirmation if this was the right way to go about implementing my use case.
I am working on a swing app. This app when it starts, should launch a service thread at the background, that keeps polling a database and does some stuff at an interval of 30 minutes.
These are the things that need to happen
Starts off a service that executes at a fixed rate of 30 minutes.
If an exception happens while the service is executing, it should notify the user and restart itself.
When the user quits the application, all backround threads should be stopped.
I have written this code below. I needed some confirmation whether this was the right way to go about building something like this. Specifically I had the below questions
The while(true) loop is used to restart the service when things go bad. Could there be any issues with this? Is there a better way of doing this?
What is the most reliable way to shutdown the entire thing when the user exits. I want the user's exit to be quick and at the same time the background thread should have completed somewhere in between. Is there someway of making the background thread signify that it has reached a checkpoint and that it can be shutdown? Like for example, if I am looping through many records in the database and when shutdown is called, if the thread is working on one record, it completes working on that record and then proceeds to shutdown?
import java.util.concurrent.*;
public class ScheduledFutureTest {
private static int counter=0;
public static void main(String[] args) {
try{
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(new Callable<Void>(){
#Override
public Void call() throws Exception {
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<?> future=schedule(scheduledExecutorService);
while(true){
try{
future.get();
}catch (Exception e){
System.out.println("Exception caught.. now need to restart scheduler");
scheduledExecutorService.shutdownNow();
// restart scheduler
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
future=schedule(scheduledExecutorService);
System.out.println("Restarted the scheduler");
}
}
}
public ScheduledFuture<?> schedule(ScheduledExecutorService scheduledExecutorService){
return scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
System.out.println(counter++);
// simulating an exception to occur
if (counter % 3 == 0) {
throw new RuntimeException("Exception thrown from runnable - counter ="+counter);
}
}
}, 0, 1, TimeUnit.SECONDS); // actually 30 minutes
}
});
// work with other stuff regarding the swing app
System.out.println(" continuing with working on other stuff ");
}catch (Exception e){
e.printStackTrace();
}
}
}
Is there any way/tool to control the threads running within a process on android platform, such as let some threads delay for a random time.
Background: I am a QA engineer. I'd like to see if some threads are forced to run slowly, what will happen to the whole app? I'd like to see other kind of errors rather than ANR. For multiple threading, if programmer doesn't use or use bad strategies to sync threads, some bugs might happen. So I want to do this kind of testing.
You only have to take care of the UIThread, well actually Android will take care of it for you. Taking that into account, try to don't do any intensive operation in this thread as you won't have full control of it (see activity lifecycle)
As long as the UIthread is fine, you won't notice a slow responding app, for the rest of threads I suggest you taking a look in different classes that will ease the task of communicating back with this UIThread;
Asynctask & Handlers, there are more options, but these two are the most important (imo)
The rest of threads, you can control them as you would in Java, even sleeping them if needed.
Let's see an example:
public class MapView extends SurfaceView implements Runnable{
Thread t = null;
SurfaceHolder holder;
boolean draw = false;
#Override
public void run() {
while (draw) {
if (!holder.getSurface().isValid())
continue;
Canvas c = holder.lockCanvas();
//Draw something
holder.unlockCanvasAndPost(c);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
void pause() {
draw = false;
try {
t.join(); // this will cause the main thread to wait for this one to
//finish and then it can safely access its data.
} catch (InterruptedException e) {
e.printStackTrace();
}
t = null;
}
void resume() {
draw = true;
t = new Thread(this);
t.start(); // This will look for our run method (this)
}
}
In this example, a normal Thread is used to control how/when and with what delay we draw. The resume and pause methods let us control that thread so we can stop drawing if the activity using it is in background and restart it when it comes back (Overriding onPause and onResume)