use the following search parameters to narrow your results:
e.g.(and 'dog' reddit:'aww' site:'imgur.com')
(and 'dog' reddit:'aww' site:'imgur.com')
see the search faq for details.
advanced search: by author, community...
Java threads question (self.java)
submitted 7 months ago by whoami4546
I am currently writing a program that works with 10 similiar threads with different priorities. My professor gave extra credit to figure out how to report that all ten threads are done and and notify the user with a Jtextfield. How would I go about doing this?
[–]Ph4g3 3 points4 points5 points 7 months ago
Here is one solution. Basically tell each thread to wait on the next before completing.
Thread[] threads = makeMyThreads(); for(Thread t : threads) { t.start(); } try { for(Thread t : threads) { t.join(); } } catch(Exception e){ /*Do your own cleanup*/} finally { //Update JTextfield }
That whole article I linked is a good resource for threads. It's a relatively easy read and goes through the basics of threads.
[–]whoami4546[S] 0 points1 point2 points 7 months ago
I need all ten threads to run at the same time.
[–]thebigkevdogg 2 points3 points4 points 7 months ago
...and they will with the above code. that code will just wait until they're all done (in parallel), then the "//Update JTextField" will happen.
[–]pjriot 0 points1 point2 points 7 months ago
Does this not defeat the purpose of threading? Genuine question...what am I missing?
[–]papercrane 3 points4 points5 points 7 months ago
Thread#join() just waits for the target thread to die before continuing execution, if the thread is already dead then it will continue automatically.
It doesn't actually tell each thread to wait for the next before continuing. Rather it will execute all the threads at once and then wait for them all to finish.
[–]ModernRonin 2 points3 points4 points 7 months ago
My professor gave extra credit to figure out how to report that all ten threads are done
There's about twenty ways.
It's tempting to create all the threads in a single ThreadGroup and then use ThreadGroup.activeCount(). But the javadocs say that activeCount() isn't always accurate. Shit like this drives me completely insane - I don't understand why you could give someone an API call and then say, "Dur! Hur! This API call doesn't do what I said it would. Ha, sucker!" Maybe this is why Sun went out of business.
If you can change the code in the threads' run() method, you could make run() call a threadHasFinished() synchronized method on some public object as the last thing they do. The threadHasFinished() method can keep a internal counter, and when the counter gets to 10, all the threads are done, and it changes the text field. Seems to me there is a small possibility of a race condition here - the thread could get suspended just after it returns from the threadHasFinished() call, but just before run() actually exits.
You could spawn ten more threads, each one calling join() on one of the original ten threads. When join() returns, the original thread is dead. Just watch out for an InterruptedException that may kick you out of the join() early. Catch this and call join() again.
You could set up a timer, and every time the timer goes off, call isAlive() on all ten threads. (You'll have to keep all ten threads in an array somewhere so you can call their .isAlive() method.) When all ten threads are dead, kill your timer, and then change the text field.
[–]bkuker 3 points4 points5 points 7 months ago
Try building a reliable solution [using activeCount()] to this problem even assuming ThreadGroup.activeCount() always returns an accurate result. You can't.
Imagine that after activeCount() has accurately counted the active threads in the group and started to execute it's return statement (say it is in the middle of unrolling the stack) one of the threads in your ThreadGroup exits?
The return value is one too many. Even if activeCount() works perfectly all it can tell you is how many threads were active very recently.
Threads starting and stopping while activeCount() is counting them will prevent it from even being able to calculate that perfect result.
[–]ModernRonin 0 points1 point2 points 7 months ago
You're right, "Active" isn't even what I care about. All I want to know is if the threads are all TERMINATED or not. Active or asleep is the wrong distinction. It isn't helpful.
[–]speek 1 point2 points3 points 7 months ago
Wouldn't it be simpler to simply call join() on each thread right in your main thread?
t1.join() t2.join() t3.join() t4.join() t5.join() t6.join() t7.join() t8.join() t9.join() t10.join()
now, when your code makes it through all that, it can only be because all 10 threads are dead. And if you put them in some sort of list or array, you can save yourself many lines of code, of course.
I don't know join() well enough to know what will happen if you call it on a thread that's already TERMINATED. I assume it would return immediately, but since I can't be absolutely certain (javadocs are silent on this issue), I didn't recommend this course of action.
I wondered that too, but I figured it's worth trying and seeing. Seems the simplest method.
I agree. Totally worth trying.
[–]Zomgondo 1 point2 points3 points 7 months ago*
You can be absolutely certain that join() on a dead thread returns immediately - programmers rely on that behavior all the time, and if they ever change it all kinds of things are going to break. But you're right, the Javadocs aren't real clear, they just say "join() waits for a thread to die."
[–]Neres28 0 points1 point2 points 7 months ago
Thankfully we don't have to rely on the docs to know what it does:
/** * Waits at most <code>millis</code> milliseconds for this thread to * die. A timeout of <code>0</code> means to wait forever. * * @param millis the time to wait in milliseconds. * @exception InterruptedException if any thread has interrupted * the current thread. The <i>interrupted status</i> of the * current thread is cleared when this exception is thrown. */ public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } } /** * Tests if this thread is alive. A thread is alive if it has * been started and has not yet died. * * @return <code>true</code> if this thread is alive; * <code>false</code> otherwise. */ public final native boolean isAlive();
[–]ModernRonin 1 point2 points3 points 7 months ago
If you rely on undocumented behavior, you are setting yourself up for a fall. If it's undocumented, that means the people who control the language can change it at any time. And your code would then be broken.
I will not recommend anyone make their code dependent on functionality that could change. It's bad engineering.
[–]Neres28 1 point2 points3 points 7 months ago
I'd never recommend that someone take the documentation to be the canonical source on program behavior. That's just plain dumb.
Thanks for being honest about that. I appreciate your candor.
Think you're totally wrong, of course. But there's much to be said for clear communication.
[–]Zomgondo 0 points1 point2 points 7 months ago
Eh, as a general rule you don't ever want to block in your main thread in any sort of GUI application (Swing, SWT, Android, Windows, anything). However it's trivial to spawn a thread that then turns around and creates the worker threads, then calls join() on all of them.
[–]elgubbo 1 point2 points3 points 7 months ago
off topic: for me one of the most painful experiences in programming was finding out that androids "AsyncTask.cancel()" sometimes works and sometimes does not...
"look at me, i will cancel this task now! GOTCHA!"
Seriously makes me want to fly to wherever these fucksticks work, with my sword, and behead them. :P
I'd get the electric chair for sure... but it'd be SOOOOOOOOOOO worth it.
[–]blargle 4 points5 points6 points 7 months ago
take a look at http://download.oracle.com/javase/1,5,0/docs/api/java/util/concurrent/CountDownLatch.html
[–]papercrane 1 point2 points3 points 7 months ago
Nice find, I've never used that class before. Looking through the javadocs it looks like CyclicBarrier would be easier though. Something like:
barrier = new CyclicBarrier(THREAD_COUNT, new Runnable() { public void run { // Update JTextField });
Then when each thread is done processing just have them call barrier.await();
Edit: I should note that part: // Update JTextField
Shouldn't really update the text field. Rather it should use SwingUtilities.invokeLater
Spawn a new thread. You'll use this to launch the 10 threads you need.
Inside that thread, spawn your worker threads and store them in a List:
List<Thread> myThreads = new ArrayList<Thread>();
// create threads and toss them in your list
Have the spawning thread call join() on all 10 threads.
for (Thread thread: myThreads) try { thread.join(); } catch (InterruptedException ie) {}
As soon as step #3 is complete, all 10 threads have died, update your JTextField.
There are other ways to do it, but this one is straightforward and doesn't require any knowledge of anything other than the Thread class... I'm not a fan of most of Java's more advanced threading management stuff.
[–]SBoots 0 points1 point2 points 7 months ago
I've done something like this before.... not sure how correct it is but it seems to work (this isn't tested)
public abstract class CallbackRunnable implements Runnable { public interface ICallbackRunnable { void onWorkComplete(); } private ICallbackRunnable _callback = null; public CallbackRunnable(ICallbackRunnable callback) { _callback = callback; } @Override public void run() { work(); if (_callback != null) _callback.onWorkComplete(); } public abstract void work(); } public class test { public static void main(String[] args) { ICallbackRunnable callback = new ICallbackRunnable() { @Override public void onWorkComplete() { // thread just finished! } }; CallbackRunnable newThreadRunnable = new CallbackRunnable(callback) { @Override public void work() { // do whatever } }; Thread newThread = new Thread(newThreadRunnable); newThread.start(); // thread will start, do work() and then execute the callback when it's done } }
Basically just creating a class that implements Runnable and in run() calling the user defined work() method and then a callback to let the user know it's done.
[–]merz1254 0 points1 point2 points 7 months ago
Call "join()" for each thread. "join()" causes the main thread to wait until that thread is complete, then it will return letting the main thread to continue.
Win32 API has a WaitForMultipleObjects function which you can pass a multitude of handles to do this process for you. Java may have a thread container that does something similar.
[–]KayRice -1 points0 points1 point 7 months ago
A queue with synchronize will work for the extra credit.
synchronize
all it takes is a username and password
create account
is it really that easy? only one way to find out...
already have an account and just want to login?
login
[–]Ph4g3 3 points4 points5 points ago
[–]whoami4546[S] 0 points1 point2 points ago
[–]thebigkevdogg 2 points3 points4 points ago
[–]pjriot 0 points1 point2 points ago
[–]papercrane 3 points4 points5 points ago
[–]ModernRonin 2 points3 points4 points ago
[–]bkuker 3 points4 points5 points ago
[–]ModernRonin 0 points1 point2 points ago
[–]speek 1 point2 points3 points ago
[–]ModernRonin 0 points1 point2 points ago
[–]speek 1 point2 points3 points ago
[–]ModernRonin 0 points1 point2 points ago
[–]Zomgondo 1 point2 points3 points ago*
[–]Neres28 0 points1 point2 points ago
[–]ModernRonin 1 point2 points3 points ago
[–]Neres28 1 point2 points3 points ago
[–]ModernRonin 0 points1 point2 points ago
[–]Zomgondo 0 points1 point2 points ago
[–]elgubbo 1 point2 points3 points ago
[–]ModernRonin 0 points1 point2 points ago
[–]blargle 4 points5 points6 points ago
[–]papercrane 1 point2 points3 points ago
[–]Zomgondo 1 point2 points3 points ago*
[–]SBoots 0 points1 point2 points ago
[–]merz1254 0 points1 point2 points ago
[–]KayRice -1 points0 points1 point ago