I am having an issue ending threads once my program my has finished. I run a threaded clock object and it works perfectly but I need to end all threads when the time ´==´ one hour that bit seems to work I just need to know how to end them. Here is an example of the code I have and this is the only thing that runs in the run method apart from one 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 keep watching the threads that are running in the debug mode of netbeans they keep running after an hour has passed not sure how to fix this. I have tried the interrupt call but it seems to do nothing.
There are two ways to stop a thread in a nice way, and one in an evil way.
For all you need access to the object of the thread (or in the first case a Runnable class that is executed on that thread).
So your first task is to make sure you can access a list of all threads you want to stop. Also notice that you need to make sure you are using threadsafe communication when dealing with objects used by several threads!
Now you have the following options
Interrupt mechanisme
Call Thread.interrupt() on each thread. This will throw an InterruptedException on the thread if you are in a blocking function. Otherwise it will only set the isInterrupted() flag, so you have to check this as well. This is a very clean and versatile way that will try to interrupt blocking functions by this thread. However many people don't understand how to nicely react to the InterruptedException, so it could be more prone to bugs.
isRunning flag
Have a boolean 'isRunning' in your thread. The while loop calls a function 'stopRunning()' that sets this boolean to false. In your thread you periodically read this boolean and stop execution when it is set to false.
This boolean needs to be threadsafe, this could be done by making it volatile (or using synchronized locking).
This also works well when you have a Runnable, which is currently the advised way of running tasks on Threads (because you can easily move Runnables to Threadpools etc.
Stop thread (EVIL)
A third and EVIL and deprecated way is to call Thread.stop(). This is very unsafe and will likely lead to unexpected behavior, don't do this!
Make sure that the loop inside every thread finishes - if it does in all the threads, it does not make sense that there are prints in the output. Just note that what you are checking in each loop condition check if the current hour is not 1 PM, not if an hour has not passed.
Also, your threads garbage collected, which means that the Garbage Collector is responsible for their destruction after termination - but in that case they should not output anything.
A volatile variable shared by all the Threads should help to achieve the goal. The importance of a volatile variable is that each of the Threads will not cache or have local copy but will need to directly read from the main memory. Once it is updated, the threads will get the 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 both reading and writing to a shared variable, then
using the volatile keyword for that is not enough. You need to use
synchronization in that case to guarantee that the reading and writing
of the variable is atomic.
Here are links that may help you to grasp the concept:
http://tutorials.jenkov.com/java-concurrency/volatile.html
http://java.dzone.com/articles/java-volatile-keyword-0
If these threads are still running after your main program has finished, then it may be appropriate to set them as daemon threads. The JVM will exit once all non-daemon threads have finished, killing all remaining daemon threads.
If you start the threads like:
Thread myThread = new MyThread();
myThread.start();
Then daemon-izing them is as simple as:
Thread myThread = new MyThread();
myThread.setDaemon(true);
myThread.start();
It's a bad practice to externally terminate threads or to rely on external mechanisms like kill for proper program termination. Threads should always be designed to self-terminate and not leave resources (and shared objects) in a potentially indeterminate state. Every time I have encountered a thread that didn't stop when it was supposed to, it was always a programming error. Go check your code and then step through the run loop in a debugger.
Regarding your thread, it should self-terminate when the hour reaches 1, but if it is below or above 1, it will not terminate. I would make sure that clock's hour count reaches one if minutes go past 59 and also check that it doesn't somehow skip 1 and increment off in to the sunset, having skipped the only tested value. Also check that clock.getHour() is actually returning the hour count instead of a dummy value or something grossly incorrect.
Have you considered using an ExecutorService ? It behaves more predictably and avoids the overhead of thread creation. My suggestion is that you wrap your while loop within one and set a time limit of 1 hr.
Using Thread.interrupt() will not stop the thread from running, it merely sends a signal to you thread. It's our job to listen for 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 Executors class with static methods to return different thread pools.
Executors.newFixedThreadPool(10)
creates a fixed thread pool of size 10 and any more jobs will go to queue for processing later
Executors.newCachedThreadPool()
starts with 0 threads and creates new threads and adds them to pool on required basis if all the existing threads are busy with some task. This one has a termination strategy that if a thread is idle for 60 seconds, it will remove that thread from the pool
Executors.newSingleThreadExecutor()
creates a single thread which will feed from a queue, all the tasks that're submitted will be processed one after the other.
You can submit your same Runnable tasks to your thread pool. Executors also has methods to get pools to which you can submit scheduled tasks, things you want to happen in future
ExecutorService service = Executors.newFixedThreadPool(10);
service.execute(myRunnableTask);
Coming to your question, when you use thread pools, you have an option to shut down them after some time elapsed like this
service.shutdown();
service.awaitTermination(60, TimeUnit.MINUTES);
Few things to pay attention
shutdown() Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.
awaitTermination() is waiting for the state of the executor to go to TERMINATED. But first the state must go to SHUTDOWN if shutdown() is called or STOP if shutdownNow() is called.
Related
I am making an online game in Java and I ran into one particular issue where I was trying to find the most efficient way to send clients spawn entity NPC packets. I of course understand how to send them but I wanted to do it off of the main game loop since it requires looping through a map of NPC's (I also made sure its thread safe). To do this I thought a BlockingQueue was my best option so I created a new thread set it to daemon then passed in a runnable object. Then whenever I needed to send one of these packets I would use the insertElement() method to add to the queue. Here is how it looks.
public class NpcAsyncRunnable implements Runnable {
private final BlockingQueue<NpcObject> blockingQueue;
public NpcAsyncRunnable() {
blockingQueue = new LinkedBlockingQueue<>();
}
#Override
public void run() {
while(true) {
try {
final NpcObject obj = blockingQueue.take();
//Run my algorithm here
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void insertElement(final NpcObject obj) {
blockingQueue.add(obj);
}
}
Now my question is how efficient is this? I am running the thread the whole time in an infinite loop because I always want it to be checking for another inserted element. However, my concern is if I have too many async threads listening would it start to clog up the CPU? I ask this because I know a CPU core can only run 1 thread of execution at a time but with hyperthreading (AMD has the same thing but its called something different) it can jump between executing multiple threads when one needs to search for something in memory. But does this infinite loop without making it sleep mean it will always be checking if the queue has a new entry? My worry is I will make a CPU core waste all its resources infinitely looping over this one thread waiting for another insertion.
Does the CPU instead auto assign small breaks to allow other threads to execute or do I need to include sleep statements so that this thread is not using way more resources than is required? How much CPU time will this use just idling?
...does this infinite loop without making it sleep mean...?
blockingQueue.take() does sleep until there's something in the queue to be taken. The Javadoc for the take method says, "Retrieves and removes the head of this queue, waiting if necessary until an element becomes available."
"Waiting" means it sleeps. Any time you are forced to write catch (InterruptedException...), it's because you called something that sleeps.
how does it know when something is added if its sleeping? It has to be running in order to check if something has been added to the queue right?
No. It doesn't need to run. It doesn't need to "check." A BlockingQueue effectively* uses object.wait() to make a thread "sleep," and it uses object.notify() to wake it up again. When one thread in a Java program calls o.wait() for any Object o, the wait() call will not return** until some other thread calls o.notify() for the same Object o.
wait() and notify() are thin wrappers for operating system-specific calls that do approximately the same thing. All the magic happens in the OS. In a nutshell;
The OS suspends the thread that calls o.wait(), and it adds the thread's saved execution context to a queue associated with the object o.
When some other thread calls o.notify(), the OS takes the saved execution context at the head of the queue (if there is one***), and moves it to the "ready-to-run" queue.
Some time later, the OS scheduler will find the saved thread context at the head of the "ready-to-run" queue, and it will restore the context on one of the system's CPUs.
At that point, the o.wait() call will return, and the thread that waited can then proceed to deal with whatever it was waiting for (e.g., an NpcAsyncRunnable object in your case.)
* I don't know whether any particular class that implements BlockingQueue actually uses object.wait() and object.notify(), but even if they don't use those methods, then they almost certainly use the same operating system calls that underlie wait() and notify().
** Almost true, but there's something called "spurious wakeup." Correctly using o.wait() and o.notify() is tricky. I strongly recommend that you work through the tutorial if you want to try it yourself.
*** o.notify() does absolutely nothing at all if no other thread is already waiting at the moment when it is called. Beginners who don't understand this often ask, "Why did wait() never return?" It didn't return because the thread that wait()ed was too late. Again, I urge you to work through the tutorial if you want to learn how to avoid that particular bug.
In a web app i have a method, this waits for another thread for generate reports if the quantity of customers is less than 10, but if greater than 10 i start my thread but without apply the join method, when the thread finish i notify by e-mail.
I'm a little afraid about the orphan threads with a large execution and the impact on the server.
Is good launch a "heavy" process in background (asynchronically) without use the join method or there is a better way to make it?
try {
thread.start();
if(flagSendEmail > 10){
return "{\"message\":\"success\", \"text\":\"you will be notified by email\"}";
}else{
thread.join(); //the customer waits until finish
}
} catch (InterruptedException e) {
LogError.saveErrorApp(e.getMessage(), e);
return "{\"message\":\"danger\", \"text\":\"can't generate the reports\"}";
}
Orphan threads aren't the problem, simply make sure that the run() method has a finally block that sends out the email.
The problem is that you have no control over the number of threads and that's got nothing to do with calling join(). (Unless you always wait for every single thread in the caller, at which point there's no point launching a background thread in the first place.)
The solution is to use an ExecutorService, which gives you a thread pool, and thus precise control over how many of these background threads are running at any one time. If you submit more tasks than the executor can handle at a given time, the remaining ones are queued up, waiting to be run. This way you can control the load on your server.
An added bonus is that because an executor service will typically recycle the same worker threads, the overhead of submitting a new task is less, meaning that you don't need to bother about whether you've got more than 10 items or not, everything can be run the same way.
In your case you could even consider using two separate executors: one for running the report generation and another one for sending out the emails. The reason for this is that you may want to limit the number of emails sent out in a busy period but without slowing report generation down.
There's no point is starting a thread if the very next thing you do is join() it.
I'm not sure I understand what you're trying to do, but if your example is on the right path, then this would be even better because it avoids creating and destroying a new thread (expensive) in the flagSendEmail <= 10 case:
Runnable r = ...;
if (flagSendEmail > 10) {
Thread thread = new Thread(r);
thread.start();
return "...";
} else {
r.run();
return ???
}
But chances are, you should not be explicitly creating new Threads at all. Any time a program continually creates and destroys threads, that's a sign that it should be using a thread pool instead. (See the javadoc for java.util.concurrent.ThreadPoolExecutor)
By the way: t.join() does not do anything to thread t. It doesn't do anything at all except wait until thread t is dead.
Yes it is safe, I don't recall seeing any Thread#join() actual invocations.
But it will depends on what are you trying to do. I don't know if you mean to use a pool or threads that generate reports or have some resource assigned. In any case you should limit yourself to a maximum number of threads for reports. If they are getting blocked or looped (for some bug or poor synchronization), allowing more and more threads will utterly clog your application.
Thread#join waits for the referred thread to die. Are those threads actually ending? Are you waiting for a thread to die just to launch another thread? Usually synchronization is done with wait() and notify() over the synchronization object.
Launching a process (Runtime#exec()) probably will make things even worse, unless it helps work around some weird limitation.
There are some tools like JConsole which can give you some heads up about threads getting locked and other issues.
In the below code:
class Test {
public static void main(String [] args) {
printAll(args);
}
public static void printAll(String[] lines) {
for(int i=0;i<lines.length;i++){
System.out.println(lines[i]);
Thread.currentThread().sleep(1000);
}
}
}
Will each String in the array lines output:
With exactly 1-second pause between lines?
With at least 1-second pause between lines?
Approximately 1-second pause. The thread can be woken up beforehand and you'll get an InterruptedException, or the thread can sleep for 1000ms and then not get to run immediately, so it will be 1000ms + microseconds (or more, if there are higher priority threads hogging the CPU).
You're also calling it wrong. It's Thread.sleep(1000);, as a static method it always acts on the current thread and you can't make other threads sleep with it.
So it will sleep for exactly 1 second to the best of it's knowledge. The thread.sleep method is not perfect. See this and other related questions:
https://stackoverflow.com/a/18737109/4615177
Calling Thread.sleep(1000) method, put the current executing thread in waiting state for the specified time. As per your program, it seems only a single threaded program hence,while The calling thread is in waiting state, no other thread is in running state, so after 1000 ms your thread will get chance to execute almost after 1000ms but not sure for other application where no of threads are going to execute.
Some points about Thread.sleep
1. it is always the current thread that is put to sleep
2. the thread might not sleep for the required time (or even at all);
the sleep duration will be subject to some system-specific granularity, typically 1ms;
3. while sleeping, the thread still owns synchronization locks it has acquired;
4. the sleep can be interrupted (sometimes useful for implementing a cancellation function);
5. calling sleep() with certain values can have some subtle, global effects on the OS
So at the end you can each String output will be with at least 1-second pause between lines.
And you calling it wrong. It is a static method..:)
It'll sleep for at least 1 second if not interrupted by some other thread. If some other thread interrupts it, InterruptedException will be thrown.
Ideally, it'll sleep for 1 second, once that time has elapsed, it will wait for it's turn to get into running state again.
Read the documentation. (Why did no one else say that?) The javadoc for Thread.sleep() says,
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers.
That's pretty vague, but that's all the guarantee you will get. The exact behavior will depend on what operating system you are running and probably on what JVM you are running.
An application that requires precise timing is called a real-time application, and there are special real-time operating systems (RTOS) that will tell you within how many microseconds of its scheduled time an event actually will occur. you can even get real-time versions of Java to run on your RTOS. http://en.wikipedia.org/wiki/Real_time_Java
I have code like this:
public class OtherClass {
// OtherClass
public synchronized static void firstMethod() {
System.out.println("FIRST METHOD");
}
public synchronized static void secondMethod() {
System.out.println("SECOND METHOD");
// In actual code I would have try catch for this but here I just didn't
// include it
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class MainClass {
// main method of MainClass
public static void main(String args[]) {
Thread firstThread = new Thread() {
public void run() {
while (true) {
OtherClass.firstMethod();
}
}
};
Thread secondThread = new Thread() {
public void run() {
while (true) {
OtherClass.secondMethod();
}
}
};
secondThread.start();
firstThread.start();
}
}
The reason I start the 2nd thread first is because I want the secondMethod of OtherClass to execute first. I should see "FIRST METHOD" and "SECOND METHOD" in the console output every 5 seconds. The reason being is that since Thread.sleep does not relinquish the lock, for 5 seconds the first thread doesn't have access to the first method because the second thread has got a lock on the class while it's in the second method which tells the thread to sleep for 5 seconds. But I get very unexpected results. All I get in the console output is "SECOND METHOD" every 5 seconds. The firstMethod isn't called.
Ignoring compilation problems in your code.
That's just coincidence. The thread scheduler simply decides to continue executing the second thread which reacquires the lock too fast.
Run it long enough (or with a shorter sleep time for faster results) and you'll see the other method get invoked.
The reason I start the 2nd thread first is because I want the secondMethod of OtherClass to execute first.
That's not how threads work. That's not what threads are for. Threads provide no guarantees of what happens before what else except where you provide explicit synchronization between them; And generally speaking, the more synchronization you use, the less you will benefit from having multiple threads.
In your example, you have explicit synchronization that prevents any concurrent executions of firstMethod() and secondMethod(), but you have nothing that guarantees which one will run first, and which one will run second. Chances are, that main() will terminate before either of them runs. At that point, it's up to the scheduler to pick which one will run when. There is no requirement that it start them in the same order that your code called their start() methods.
Your example may be educational, but it also is an example of when not to use threads. Your synchronization is very heavy handed. Your program basically does two things, firstMethod() and secondMethod(), and the synchronization insures that they can not be overlapped. In production software, if you have two tasks that must not overlap, then it'll simplify your program's logic if they are always performed by the same thread.
All I get in the console output is "SECOND METHOD" every 5 seconds. The firstMethod isn't called.
Your question was edited before I got to see it, so I don't know whether you're talking about the original version, or the fixed version. But in any case:
The synchronization in your program does not guarantee that the two threads take turns. All it does is prevent them both from printing at the same time.
Each of your threads runs a loop that grabs the lock, prints something, releases the lock, and then immediately tries to grab the lock again. When a running thread releases a lock, and then immediately tries to get it again, the chances are it will succeed. It doesn't matter that some other thread was waiting for the lock. The OS doesn't know what your program is trying to accomplish, but it does know that it can make more efficient use of the CPU by letting a thread continue to run instead of blocking it and un-blocking some other thread.
You will need to use some additional synchronization to make the threads take turns, but like I said, in a real program, the more synchronization you use, the less benefit there is to using threads.
Your processor won't execute your Threads at the same time; it'll run your second thread every time bevore your first thread.
The behaviour is clear: Your processor executes your second thread. Then, the processor executes your first thread and sees that it is locked by your second thread. After 5 seconds, your second thread is called again. It makes the output, releases the lock and locks it again. If your first thread is called again, it is locked again.
To fix this, add Thread.yield() at the end of your while. This will make the processor call the first thread before continuing to execute your second thread (the first thread won't be the only one that is called, it just removes your second thread 1 time from it's execution). Then your first thread gets the lock, waits 5 seconds, outputs and calls Thread.yield(); then your second thread gets the lock again and so on.
What you are experiencing is thread starvation. In your case, one thread is being blocked indefinitely waiting to enter a synchronization block because the other thread is constantly allowed access.
To overcome thread starvation you need to employ some sort of fairness locking. Locks that are conceived as fair give priority to the threads waiting the longest to acquire said lock. Such a locking strategy eliminates the possibility of thread starvation and insures all waiting threads will be executed at some time.
Fairness locking in Java can easily be accomplished by using a ReentrantLock with a fairness parameter set to true.
In javadoc there is said that yield method
Causes the currently executing thread object to temporarily pause and allow other threads to execute.
And Katherine Sierra and Bert Bates SCJP book says that
yield() is supposed to do is
make the currently running thread head back to runnable to allow other threads of
the same priority to get their turn.
So what actually method is doing?
Given a multi-threaded application, yield will cause the currently executing thread to pause execution and be set in a waiting state. The JVM will then begin running another thread that was previously in a waiting state.
I believe the same thread that just yielded could technically be scheduled to start again.
And I have yet to see this in the wild though. So I think it is safe to avoid.
To elaborate:
In a multi-threaded environment threads are scheduled and unscheduled off and on at the JVM's will. So, even if yield is not called in code, your thread can/will automatically yield to other threads when the JVM decides it should. This allows multi-threading to work in an environment with only one processing core.
Calling yield simply tells the JVM to put the current thread in a waiting state even if the JVM wasn't going to.
I shall attempt an illustration:
The following is a very simplified illustration of the execution of 2 threads over time (assume 1 core)-
Thread\Time 1 2 3 4 5 6 7 8 9
Thread 1 ----------- ----- -------
Thread 2 ------- ---------- ------
Whenever you see a '-' that means a thread is executing. A ' ' means that the thread is waiting. As you can see, only 1 thread can actually run at a time. So, while 1 runs, the other waits. What yield is intended to do is give other threads a chance to run ahead of the currently running thread.
yield() is generally used when you are waiting on a thread for something to occur but don't want to block the CPC cycles with something like while(condition){ ...} . The way yield() works differ from platform to platform and depends on the Thread Scheduler and you shouldn't rely on it behaving in a particular way.
It originates from the time of cooperative multitasking.
The basic idea is, the processor executes only one thread until:
this thread ends
this thread does some blocking operation, like object.wait() or Thread.sleep, waiting on some IO operation to complete, waiting for some object monitor, or similar.
this thread invokes Thread.yield().
In each of this cases the thread scheduler then selects another thread to execute. So, to be fair to other threads, you would in longer loops without any blocking operations regularly call yield(). (If no other thread is ready to run, then the same thread would be scheduled again, so no really big performance loss.)
In modern VMs thread switching can occur on any point, not only these listed, threads may even be executed simultaneously, so it is not really necessary, and some VMs may ignore it altogether (similar to System.gc().)
yield() method is there to make sure that all same priority threads in a application would not cause starvation. For e.g. five threads are there in a application and all of them are of same priority. Now suppose one thread got chance to run and this thread is taking so long to complete its task and hence other threads wont get chance to run. So to avoid this kind of situations yield() is there to rescue.
Ultimately, the call to yield() results in calling os methods like this, which in principle would put the task itself back in to the run queue and let the next task run (source):
/**
* sys_sched_yield - yield the current processor to other threads.
*
* This function yields the current CPU to other tasks. If there are no
* other threads running on this CPU then this function will return.
*/
SYSCALL_DEFINE0(sched_yield)
{
/*
* lock this runqueue and disable interrupts.
*/
struct rq *rq = this_rq_lock();
schedstat_inc(rq, yld_count);
current->sched_class->yield_task(rq);
/*
* Since we are going to call schedule() anyway, there's
* no need to preempt or enable interrupts:
*/
__release(rq->lock);
spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
_raw_spin_unlock(&rq->lock);
preempt_enable_no_resched();
schedule();
return 0;
}
Threads may be in states ready (runnable), blocked (e.g., waiting for some io to finish), or running; this is common to all thread implementations, although some particular implementations may have more states.
Yield causes the thread to change from running to runnable, and wait for the scheduler to change it to running again, in the future. This is what is meant in the SCJP book.
To the thread, it seems like it has been paused for a while, like described in the javadoc. So both statements are correct, just differently phrased.
Hope it helps!
package yield;
public class ThreadYieldApp {
Thread th1 = new Thread("Thread 1") {
public void run() {
for(int i = 0; i <= 10; i++) {
System.out.println("Before Yield - " + Thread.currentThread().getName() + " at index - " + i);
//Currently pauses the thread and checks for other threads of same priority, and passes control to it based on Thread Scheduler pick
Thread.yield();
System.out.println("Currently running - " + Thread.currentThread().getName() + " at index - " + i);
}
}
};
Thread th2 = new Thread("Thread 2") {
public void run() {
for(int i = 0; i <= 10; i++) {
System.out.println("Currently running - " + Thread.currentThread().getName() + " at index - " + i);
}
}
};
public static void main(String[] args) {
ThreadYieldApp threadYieldApp = new ThreadYieldApp();
threadYieldApp.th1.start();
threadYieldApp.th2.start();
}
//Happy coding -- Parthasarathy S
}