End Java threads after executing while statement

I am having trouble terminating threads after completing my program. I run the stream object of the clock and it works fine, but I need to finish all the threads, when the time "==" for one hour seems to be working, I just need to know how to finish them. Here is an example of the code I have, and this is the only thing that runs in the run method other than the single int defined above this code.

@Override public void run() { int mins = 5; while(clock.getHour() != 1) { EnterCarPark(); if(clock.getMin() >= mins) { System.out.println("Time: " + clock.getTime() + " " + entryPoint.getRoadName() + ": " + spaces.availablePermits() + " Spaces"); mins += 5; } } } 

But when you continue to monitor threads running in netbeans debugging mode, they continue to work after an hour has passed, not sure how to fix it. I tried the interrupt call, but it seems to do nothing.

enter image description here

+7
java multithreading
source share
7 answers

There are two ways to stop the flow in a beautiful way, and one in an evil way.

For everything, you need access to the thread object (or in the first case, the Runnable class that runs on this thread).

So, your first task is to make sure that you can access the list of all the threads you want to stop. Also note that you need to make sure that you use streaming communication when working with objects used by multiple threads!

You now have the following options

Interrupt mechanism

Call Thread.interrupt() for each thread. This will InterruptedException in the thread if you are in a blocking function. Otherwise, it will set the isInterrupted() flag, so you should check this out. This is a very clean and universal way that will try to interrupt blocking functions with this thread. However, many people do not understand how to respond well to InterruptedException , so it may be more error prone.

isRunning flag

You have a boolean value of isRunning in your thread. The while loop calls the function "stopRunning ()", which sets this boolean to false. In your thread, you periodically read this boolean and terminate when it is set to false. This boolean value must be threaded, this can be done by making it volatile (or using a synchronized lock).

This also works well when you have Runnable , which is currently the recommended way to run tasks in Threads (because you can easily move Runnables to Threadpools , etc.

Stop Stream (EVIL)

The third and EVIL and obsolete way is to call Thread.stop() . This is very dangerous and most likely will lead to unexpected behavior, do not do this!

+8
source share

Make sure that the loop inside each thread is completed - if it runs in all threads, it makes no sense that the output has fingerprints. Just note that what you check in each state of the loop checks if the current hour is not the hour.

In addition, garbage of your threads has been collected, which means that the garbage collector is responsible for destroying them after completion, but in this case they should not output anything.

+2
source share

Do you consider using the ExecutorService? It behaves more predictably and avoids the overhead of creating threads. My suggestion is that you end the while loop within one and set a time limit of 1 hour.

+1
source share

A mutable variable shared by all Threads should help achieve the goal. The importance of the volatile variable is that each thread will not cache or have a local copy, but will have to be read directly from main memory. Once it is updated, the streams will receive fresh data.

  public class A{ public static volatile boolean letThreadsRun = true; } // inside your Thread class @Override public void run() { // there will come a point when A.letThreadsRun will be set to false when desired while(A.letThreadsRun) { } } 

If two threads are simultaneously reading and writing to a common variable, then using the volatile keyword is not enough for this. You should use synchronization in this case to ensure that the reading and writing of the variable is atomic.

Here are links that can help you understand the concept:

http://tutorials.jenkov.com/java-concurrency/volatile.html

http://java.dzone.com/articles/java-volatile-keyword-0

+1
source share

If these threads are still running after the completion of your main program, it may be appropriate to set them as daemon threads. The JVM will exit as soon as all non-demon threads run out, destroying all remaining daemon threads.

If you start topics such as:

 Thread myThread = new MyThread(); myThread.start(); 

Then their demonization is as simple as:

 Thread myThread = new MyThread(); myThread.setDaemon(true); myThread.start(); 
+1
source share

It is bad practice to externally terminate threads or to rely on external mechanisms such as kill to properly terminate a program. Streams should always be designed to terminate themselves and not leave resources (and shared objects) in a potentially uncertain state. Each time I came across a thread that did not stop when it was supposed to, it was always a programming error. Go check your code, and then go to the run loop in the debugger.

As for your thread, it should automatically end when the hour reaches 1, but if it is below or above 1, it will not stop. I would make sure that the number of hours of the hours reaches one if the minutes pass by 59, and also make sure that it does not miss 1 and does not increase before sunset, skipping only the verified value. Also check that clock.getHour () actually returns the number of hours instead of a dummy value or something is roughly wrong.

+1
source share

Using Thread.interrupt () will not stop the thread from starting, it just sends you a signal. It is our job to listen to this signal and act accordingly.

 Thread t = new Thread(new Runnable(){ public void run(){ // look for the signal if(!Thread.interrupted()){ // keep doing whatever you're doing } } }); // After 1 hour t.interrupt(); 

But instead of doing all this work, consider using an ExecutorService. You can use the Executors class with static methods to return various thread pools.

Executors.newFixedThreadPool (10)

  • creates a fixed pool of threads of size 10 and more jobs will be sent to the queue for further processing

Executors.newCachedThreadPool ()

  • starts with 0 threads and creates new threads and adds them to the pool on the required basis if all existing threads are busy with some task. It has a termination strategy which, if a thread is idle for 60 seconds, will remove this thread from the pool

Executors.newSingleThreadExecutor ()

  • creates one thread that will be loaded from the queue, all tasks that were sent will be processed one by one.

You can submit the same Runnable tasks to the thread pool. Artists also have methods for receiving pools to which you can send scheduled tasks, what do you want in the future

 ExecutorService service = Executors.newFixedThreadPool(10); service.execute(myRunnableTask); 

Approaching your question, when you use thread pools, you have the option to disable them after some time has passed as

 service.shutdown(); service.awaitTermination(60, TimeUnit.MINUTES); 

A little to pay attention to

shutdown () Starts an orderly shutdown in which previously assigned tasks are executed, but new tasks will not be accepted. A call has no additional effect if it is already turned off.

awaitTermination () waits until the state of the worker goes to TERMINATED. But first, the state should go to SHUTDOWN if shutdown () is called, or STOP if shutdownNow () is called.

+1
source share

All Articles