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
Related
For example I have some code block which takes more than 30 seconds to execute but I want to stop that if it takes more than 30 seconds. I am trying with executor.shutdown(), executor.awaitTermination(30, TimeUnit.SECONDS) and executor.shutdownNow(); but i can not understand where I have to write my code block which I want to terminate after a specific time. Please give an perfect example.
It is pretty simple: when using threads there is no reliable way to kill that thread ( see here for example).
The only choice: start another JVM in another process - because that you can actually kill. See here for details.
Of course - this is rather not the way to go. A better way would be to implement your long-running-task in a way that regularly checks for "cancel" commands for example.
The way to go with your methods mentioned, you just add your task to the executor, then in the next line of code put executor.shutdown(); It restricts your executor from taking other tasks and then your actually put executor.awaitTermination(30, TimeUnit.SECONDS) to set the "timer" to wait for the task to complete during this time
A simple samle code snipet:
ExecutorService taskExecutor = Executors.newFixedThreadPool(1);
taskExecutor.execute(new MyTask());
taskExecutor.shutdown();
try {
taskExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
...
}
I'm trying to write an integration test that causes an InterruptedException to be raised from the production code:
#Test
public void test() {
productionObject = new ProductionObject(
com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor());
Thread.currentThread().interrupt();
assertThat(productionObject.execute(), equalTo(defaultResponse));
}
Inside productionObject's implementation:
try {
for (Future<T> future : executorService.invokeAll(tasks))) {
results.add(future.get());
}
return results;
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // preserve interrupt flag
return defaultResponse;
}
Inside AbstractQueuedSynchronizer.acquireSharedInterruptibly() I see:
if (Thread.interrupted())
throw new InterruptedException();
So I would expect this test to pass consistently.
I've seen this fail in our build server (results are returned rather than defaultResponse). I've been unable to reproduce the failure locally, running the test in a while (true) loop, and simulating higher load by running glxgears with software rendering ;-) Can anyone spot my mistake, give me some suggestions on where to look, or suggest tools that could help me?
Strange. I read the code the same way you do. I see:
FutureTask.get() calls Sync.get(). I assume we are dealing with FutureTask here.
Sync.get() calls Sync.innerGet()
Sync.innerGet() calls acquireSharedInterruptibly(0);
Which has the code right off:
if (Thread.interrupted())
throw new InterruptedException();
I would think that this would always throw. Maybe there is some sort of race condition so the thread does not yet know that it has been interrupted? Have you tried to sleep for 100ms after you interrupt the thread?
I just ran the following test on my multi-cpu Mac and it never fails so it does not look like a race condition -- at least with my architecture and JRE version 1.6.0_41.
for (long i = 0; i < 10000000; i++) {
Thread.currentThread().interrupt();
assertTrue(Thread.interrupted());
}
Using sameThreadExecutor() in this context might actually be contra-productive since the interrupt might than occur in one of the tasks. Otherwise the code looks fine. Try using kicking off actual other threads and let one of the tasks wait long enough for your interrupt.
I've "fixed" this by interrupting the thread from within the Callable rather than from the test method itself. This makes the interruption occur closer to call to acquireSharedInterruptibly().
I can only imagine that somewhere on the code path the interrupt flag is sometimes being cleared (perhaps by JUnit or Maven surefire, which are executing test methods in parallel). I've probably only reduced the likelihood of the race condition, rather than fixing it :-/
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.
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.
I can't use shutdown() and awaitTermination() because it is possible new tasks will be added to the ThreadPoolExecutor while it is waiting.
So I'm looking for a way to wait until the ThreadPoolExecutor has emptied it's queue and finished all of it's tasks without stopping new tasks from being added before that point.
If it makes any difference, this is for Android.
Thanks
Update: Many weeks later after revisiting this, I discovered that a modified CountDownLatch worked better for me in this case. I'll keep the answer marked because it applies more to what I asked.
If you are interested in knowing when a certain task completes, or a certain batch of tasks, you may use ExecutorService.submit(Runnable). Invoking this method returns a Future object which may be placed into a Collection which your main thread will then iterate over calling Future.get() for each one. This will cause your main thread to halt execution until the ExecutorService has processed all of the Runnable tasks.
Collection<Future<?>> futures = new LinkedList<Future<?>>();
futures.add(executorService.submit(myRunnable));
for (Future<?> future:futures) {
future.get();
}
My Scenario is a web crawler to fetch some information from a web site then processing them. A ThreadPoolExecutor is used to speed up the process because many pages can be loaded in the time. So new tasks will be created in the existing task because the crawler will follow hyperlinks in each page. The problem is the same: the main thread do not know when all the tasks are completed and it can start to process the result. I use a simple way to determine this. It is not very elegant but works in my case:
while (executor.getTaskCount()!=executor.getCompletedTaskCount()){
System.err.println("count="+executor.getTaskCount()+","+executor.getCompletedTaskCount());
Thread.sleep(5000);
}
executor.shutdown();
executor.awaitTermination(60, TimeUnit.SECONDS);
Maybe you are looking for a CompletionService to manage batches of task, see also this answer.
(This is an attempt to reproduce Thilo's earlier, deleted answer with my own adjustments.)
I think you may need to clarify your question since there is an implicit infinite condition... at some point you have to decide to shut down your executor, and at that point it won't accept any more tasks. Your question seems to imply that you want to wait until you know that no further tasks will be submitted, which you can only know in your own application code.
The following answer will allow you to smoothly transition to a new TPE (for whatever reason), completing all the currently-submitted tasks, and not rejecting new tasks to the new TPE. It might answer your question. #Thilo's might also.
Assuming you have defined somewhere a visible TPE in use as such:
AtomicReference<ThreadPoolExecutor> publiclyAvailableTPE = ...;
You can then write the TPE swap routine as such. It could also be written using a synchronized method, but I think this is simpler:
void rotateTPE()
{
ThreadPoolExecutor newTPE = createNewTPE();
// atomic swap with publicly-visible TPE
ThreadPoolExecutor oldTPE = publiclyAvailableTPE.getAndSet(newTPE);
oldTPE.shutdown();
// and if you want this method to block awaiting completion of old tasks in
// the previously visible TPE
oldTPE.awaitTermination();
}
Alternatively, if you really no kidding want to kill the thread pool, then your submitter side will need to cope with rejected tasks at some point, and you could use null for the new TPE:
void killTPE()
{
ThreadPoolExecutor oldTPE = publiclyAvailableTPE.getAndSet(null);
oldTPE.shutdown();
// and if you want this method to block awaiting completion of old tasks in
// the previously visible TPE
oldTPE.awaitTermination();
}
Which could cause upstream problems, the caller would need to know what to do with a null.
You could also swap out with a dummy TPE that simply rejected every new execution, but that's equivalent to what happens if you call shutdown() on the TPE.
If you don't want to use shutdown, follow below approaches:
Iterate through all Future tasks from submit on ExecutorService and check the status with blocking call get() on Future object as suggested by Tim Bender
Use one of
Using invokeAll on ExecutorService
Using CountDownLatch
Using ForkJoinPool or newWorkStealingPool of Executors(since java 8)
invokeAll() on executor service also achieves the same purpose of CountDownLatch
Related SE question:
How to wait for a number of threads to complete?
You could call the waitTillDone() on Runner class:
Runner runner = Runner.runner(10);
runner.runIn(2, SECONDS, runnable);
runner.run(runnable); // each of this runnables could submit more tasks
runner.waitTillDone(); // blocks until all tasks are finished (or failed)
// and now reuse it
runner.runIn(500, MILLISECONDS, callable);
runner.waitTillDone();
runner.shutdown();
To use it add this gradle/maven dependency to your project: 'com.github.matejtymes:javafixes:1.0'
For more details look here: https://github.com/MatejTymes/JavaFixes or here: http://matejtymes.blogspot.com/2016/04/executor-that-notifies-you-when-task.html
Try using queue size and active tasks count as shown below
while (executor.getThreadPoolExecutor().getActiveCount() != 0 || !executor.getThreadPoolExecutor().getQueue().isEmpty()){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}