What is the benefit of ThreadGroup in java over creating separate threads? - java

Many methods like stop(), resume(), suspend() etc are deprecated.
So is it useful to create threads using ThreadGroup?

Using ThreadGroup can be a useful diagnostic technique in big application servers with thousands of threads. If your threads are logically grouped together, then when you get a stack trace you can see which group the offending thread was part of (e.g. "Tomcat threads", "MDB threads", "thread pool X", etc), which can be a big help in tracking down and fixing the problem.

Don't use ThreadGroup for new code. Use the Executor stuff in java.util.concurrent instead.

Somewhat complimentary to the answer provided (6 years ago or so). But, while the Concurrency API provides a lot of constructs, the ThreadGroup might still be useful to use. It provides the following functionality:
Logical organisation of your threads (for diagnostic purposes).
You can interrupt() all the threads in the group. (Interrupting is perfectly fine, unlike suspend(), resume() and stop()).
You can set the maximum priority of the threads in the group. (not sure how widely useful is that, but there you have it).
Sets the ThreadGroup as a daemon. (So all new threads added to it will be daemon threads).
It allows you to override its uncaughtExceptionHandler so that if one of the threads in the group throws an Exception, you have a callback to handle it.
It provides you some extra tools such as getting the list of threads, how many active ones you have etc. Useful when having a group of worker threads, or some thread pool of some kind.

The short answer is - no, not really. There's little if any benefit to using one.
To expand on that slightly, if you want to group worker threads together you're much better off using an ExecutorService. If you want to quickly count how many threads in a conceptual group are alive, you still need to check each Thread individually (as ThreadGroup.activeCount() is an estimation, meaning it's not useful if the correctness of your code depends on its output).
I'd go so far as to say that the only thing you'd get from one these days, aside from the semantic compartmentalisation, is that Threads constructed as part of a group will pick up the daemon flag and a sensible name based on their group. And using this as a shortcut for filling in a few primitives in a constructor call (which typically you'd only have to write once anyway, sicne you're probably starting the threads in a loop and/or method call).
So - I really don't see any compelling reason to use one at all. I specifically tried to, a few months back, and failed.
EDIT - I suppose one potential use would be if you're running with a SecurityManager, and want to assert that only threads in the same group can interrupt each other. Even that's pretty borderline, as the default implementation always returns true for a Thread in any non-system thread group. And if you're implementing your own SecurityManager, you've got the possibility to have it make its decision on any other criteria (including the typical technique of storing Threads in collections as they get created).

Great answer for #skaffman. I want to add one more advantage:
Thread groups helps manipulating all the threads which are defined in this at once.

Related

Are all Java apps single-threaded unless the programmer explicitly creates Threads or implementations of Runnable?

I'm trying to understand how Java (and the JVM) create threads under the hood.
I read Java Concurrency in Practice, and I couldn't find a good explanation of whether or not all Java apps are, by default, single- or multi-threaded.
On the one hand, from the POV of a developer: I write a pile of sequential code without creating Thread instances or implementing Runnable anywhere. Do I need to synchronize anything? Should I be making double-sure my classes are thread-safe? If so, should I stop using POJOs that have mutable fields? I read that the JVM will create multiple threads under the hood for its own business. Is the JVM also creating threads to run my application without me explicitly creating those threads?
On the other hand: I write a pile of code in which I explicitly create Threads and Runnable implementations. Does the JVM spin off its own threads to "help" my multi-threaded code run faster?
It's entirely possible I'm not even thinking about the JVM's thread handling in the right way. But, I'm an entry-level Java developer, and I hate that I find this confusing.
On the one hand, from the POV of a developer: I write a pile of sequential code without creating Thread instances or implementing
Runnable anywhere. Do I need to synchronize anything? Should I be
making double-sure my classes are thread-safe? If so, should I stop
using POJOs that have mutable fields?
The straightforward answer is that no, you do not need to proactively make your objects thread-safe to protect them from concurrent access by threads you did not create.
Generally speaking, threads that interact concurrently with the code and classes you write1 won't be be created unless you do something yourself that is known to create threads, and then you organize to share an object instance between threads. Creating a Thread object is one example of creating a thread, but there are others. Here is a non-exhaustive list:
Using Executor or ExecutorService implementations which use threads (most of them).
Use a concurrent Stream method e.g., by creating a stream with the parallelStream method.
Use a library method which creates threads behind the scenes.
So generally threads don't just pop out of nowhere but rather as a result of something you do. Even if a library creates threads that you don't know about, it doesn't matter for your concern because unless documented otherwise they will not be accessing your objects, or will use locking to ensure they access them in a serialized fashion (or the library is seriously broken).
So you generally don't need to worry about cross-thread synchronization except in places where you know threads are being used. So by default you don't need to make your objects thread-safe.
1 I'm making this distinction about "interact with code you write" because a typical JVM will use several threads behind the scenes, even if you never create any yourself, for housekeeping tasks like garbage collection, calling finalizers, listening for JMX connections, whatever.
Is the app code you wrote single- or multi-threaded? Unless you explicitly took steps to create new threads – for example, by doing something like Thread t = new Thread(); – your app code will be single-threaded.
Are there multiple threads running in a single JVM? Yes, always – there will be various things running in the background that have nothing to do with the code you wrote (like the garbage collector).
Should you guard against concurrency concerns? With a single-threaded app, there is no need. However, if your code itself creates one (or more) threads, or if your code is packaged up in some manner to be used by other app creators (maybe you've created a data structure for others to use in their code), then you might need to take steps for concurrency correctness. In the case of creating code for others to use, it's perfectly fine to declare in Javadoc that your code is not threadsafe. For example, ArrayList (https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html) says "Note that this implementation is not synchronized" along with suggested workarounds.

Java, why need to use synchronization? instead of using a single thread?

While reading about Java synchronized, I just wondered, if the processing should be in synchronization, why not just creating a single thread (not main thread) and process one by one instead of creating multiple threads.
Because, by 'synchronized', all other threads will be just waiting except single running thread. It seems like the only single thread is working in the time.
Please advise me what I'm missing it.
I would very appreciate it if you could give some use cases.
I read an example, that example about accessing bank account from 2 ATM devices. but it makes me more confused, the blocking(Lock) should be done by the Database side, I think. and I think the 'synchronized' would not work in between multiple EC2 instances.
If my thinking is wrong, please fix me.
If all the code you run with several threads is within a synchronized block, then indeed it makes no difference vs. using a single thread.
However in general your code contains parts which can be run on several threads in parallel and parts which can't. The latter need synchronization but not the former. By using several threads you can speed up the "parallelisable" bits.
Let's consider the following use-case :
Your application is a internet browser game. Every player has a score and can click a button. Every time a player clicks the button, their score is increased and their opponent's is decreased. The first player to reach 10 wins.
As per the nature of the game, and to single a unique winner, you have to consider the two counters increase (and the check for the winner) atomically.
You'll have each player send clickEvents on their own thread and every event will be translated into the increase of the owner's counter, the check on whether the counter reached 10 and the decrease of the opponent's counter.
This is very easily done by synchronizing the method which handles modifying the counters : every concurrent thread will try to obtain the lock, and when they do, they'll execute the code (and finally release the lock).
The locking mechanism is pretty lightweight and only requires a single keyword of code.
If we follow your suggestion to implement another thread that will handle the execution, we'd have to implement the whole thread management logic (more code), to initialize that Thread (more resource) and even so, to guarantee fairness in the handling of events, you still need a way for your client threads to pass the event to your executor thread. The only way I see to do so, is to implement a BlockingQueue, which is also synchronized to prevent the race condition that naturally occurs when trying to add elements from two other thread.
I honnestly don't see a way to resolve this very simple use-case without synchronization (or implementing your own locking algorithm that basically does the same).
You can have a single thread and process one-by-one (and this is done), but there are considerable overheads in doing so and it does not remove the need for synchronization.
You are in a situation where you are starting with multiple threads (for example, you have lots of simultaneous web sessions). You want to do a part of the processing in a single thread - let's say updating some common structure with some new data. You need to pass the new data to the single thread - how do you get it there? You would have to use some kind of message queue (or an equivalent thing) and have the single thread pick requests off the message queue and that would have have to be synchronized anyway, plus there is the overhead of managing the queue, plus the issue that you need to get a reply back from the single thread asynchronously. So you are back to square one.
This technique is used where the processing you need to do is considerable and you don't want to block your main threads for a long time.
In summary: having a single thread does not remove the need for synchronization.

When should one create new Thread Groups

I was wondering, what are the advantages of assigning threads to a thread group instead of containing them all in one (The Main) group?
Assuming there are 10 or more constantly active threads, and a couple of threads been initiated every now and again as the application requires, how would one approach grouping these?
Thanks,
Adam.
There is no advantage at all. ThreadGroups are there for backward compatibility, but I've never seen them used.
Here's what Brian Goetz (author of Java Concurrency in Practice - the bible) said about them a long time ago:
The ThreadGroup class was originally intended to be useful in
structuring collectionsof threads into groups. However, it turns out
that ThreadGroup is not all that useful. You are better off simply
using the equivalent methods in Thread. ThreadGroup does offer one
useful feature not (yet) present in Thread: the uncaughtException()
method. When a thread within a thread group exits becauseit threw an
uncaught exception, the ThreadGroup.uncaughtException() method
is called. This gives you an opportunity to shut down the system, write
a message to a log file, or restart a failed service.
Threads now have an uncauht exception handler, and this single reason to use thread groups isn't valid anymore.

Do Java threads have a tree structure?

I have several threads. And I'd like to create sub-threads in one of them. So I'd like know whether java thread has a tree structure. Or the new created sub-threads is just the sibling of other threads. And What's the resource allocation strategy when these thread are competing for resources? Does the parent thread has higher priority ?
Thanks.
Jeff
Threads do not strictly have a tree structure. However, you can use ThreadGroups to make a hierarchical nesting of Threads and other ThreadGroups.
I don't believe that there is a hard rule for thread priority inside groups, as each thread can be set separately.
Why do you need "sub-threads"? In my experience, Thread should be avoided in favor of ExecutorService. The service won't give you a hierarchy of stuff easily, but I'm having a hard time thinking of a case where the hierarchy would be useful.
There's no thread hierarchy, all threads are siblings of each other. There is no concept of "parent thread" or "child thread". You'll have to be more specific about what you mean by resource allocation strategy -- what resources are you referring to?
If it's memory (by far the most common type of resource), then the answer is that the memory allocator is thread safe: multiple simultaneous allocations happening on different threads will always work correctly. If you run out of memory, then some unlucky thread is going to get an OutOfMemoryError.
If you're referring to other types of resources, then it depends entirely on the implementation of the resource. It's either going to be thread-safe or non-thread-safe. If it's thread-safe, you can allocate the resources freely from multiple threads. If it's not thread-safe, then read the documentation for that type of resource.
There is no concept of "subthread" in the way you describe, certainly no (apparent) tree structure. You can adjust the priority of threads if you like, though the actual meaning of thread priority is essentially undefined (unless you go to RTSJ). CPU resource allocation, by and large, is managed by the OS scheduler... you can try to influence it with priorities, but again that's a dicey proposition.
If you are looking for a framework to break a problem into subcomponents and process them concurrently, look at JDK5/JDK6's java.util.concurrent package, with specific attention to Callable and the Executor framework. Also, the ForkJoin framework might match.
The closest that there is to a thread hierarchy in Java is the ThreadGroup. By default, every application thread goes into the same ThreadGroup, but you can create new ThreadGroups and create new Threads within them. ThreadGroups are inherently hierarchical, and offer methods for doing things like enumerating the threads and child groups, interrupting all threads, setting a default uncaught exception handler, and so on.
Unfortunately, this doesn't do what you want to do. In particular, thread groups are not taken into account when allocating resources or scheduling.
There is a setMaxPriority method, but it only (indirectly) affects new threads or existing threads that change priority. Existing threads whose current priority is greater than the new "max" are not changed. So even this is not much use if you want to alter the priority of a number of threads.
(I understand, that the primary motivation of thread groups was to enable things like suspending or killing a bunch1 of related threads. But that use-case went out of the window when the Sun engineers realized that suspending and killing threads was fundamentally unsafe ... and deprecated the Thread API methods for doing that.)
1 - Anyone know the proper collective noun for a group of threads is?
Thread inherit a default priority from their parents (the one which created them) however this is just a hint and is ignored in many cases on most OSes.
Threads are designed to share resources as much as possible in as light wieght (ie simple) way possible. If you want to manage resources of tasks you need to have different processes. However these are not simple or light weight i.e they are much more expensive resource and code complexity wise.
What sort of problem are you trying to solve? It is likely for any problem there is a fairly simple solution.

Are Thread.stop and friends ever safe in Java?

The stop(), suspend(), and resume() in java.lang.Thread are deprecated because they are unsafe. The Oracle recommended work around is to use Thread.interrupt(), but that approach doesn't work in all cases. For example, if you are call a library method that doesn't explicitly or implicitly check the interrupted flag, you have no choice but to wait for the call to finish.
So, I'm wondering if it is possible to characterize situations where it is (provably) safe to call stop() on a Thread. For example, would it be safe to stop() a thread that did nothing but call find(...) or match(...) on a java.util.regex.Matcher?
(If there are any Oracle engineers reading this ... a definitive answer would be really appreciated.)
EDIT: Answers that simply restate the mantra that you should not call stop() because it is deprecated, unsafe, whatever are missing the point of this question. I know that that it is genuinely unsafe in the majority of cases, and that if there is a viable alternative you should always use that instead.
This question is about the subset cases where it is safe. Specifically, what is that subset?
Here's my attempt at answering my own question.
I think that the following conditions should be sufficient for a single thread to be safely stopped using Thread.stop():
The thread execution must not create or mutate any state (i.e. Java objects, class variables, external resources) that might be visible to other threads in the event that the thread is stopped.
The thread execution must not use notify to any other thread during its normal execution.
The thread must not start or join other threads, or interact with then using stop, suspend or resume.
(The term thread execution above covers all application-level code and all library code that is executed by the thread.)
The first condition means that a stopped thread will not leave any external data structures or resources in an inconsistent state. This includes data structures that it might be accessing (reading) within a mutex. The second condition means that a stoppable thread cannot leave some other thread waiting. But it also forbids use of any synchronization mechanism other that simple object mutexes.
A stoppable thread must have a way to deliver the results of each computation to the controlling thread. These results are created / mutated by the stoppable thread, so we simply need to ensure that they are not visible following a thread stop. For example, the results could be assigned to private members of the Thread object and "guarded" with a flag that is atomically by the thread to say it is "done".
EDIT: These conditions are pretty restrictive. For example, for a "regex evaluator" thread to be safely stopped, if we must guarantee that the regex engine does not mutate any externally visible state. The problem is that it might do, depending on how you implement the thread!
The Pattern.compile(...) methods might update a static cache of compiled
patterns, and if they did they would (should) use a mutex to do it. (Actually, the OpenJDK 6.0 version doesn't cache Patterns, but Sun might conceivably change this.)
If you try to avoid 1) by compiling the regex in the control thread and supplying a pre-instantiated Matcher, then the regex thread does mutate externally visible state.
In the first case, we would probably be in trouble. For example, suppose that a HashMap was used to implement the cache and that the thread was interrupted while the HashMap was being reorganized.
In the second case, we would be OK provided that the Matcher had not been passed to some other thread, and provided that the controller thread didn't try to use the Matcher after stopping the regex matcher thread.
So where does this leave us?
Well, I think I have identified conditions under which threads are theoretically safe to stop. I also think that it is theoretically possible to statically analyse the code of a thread (and the methods it calls) to see if these conditions will always hold. But, I'm not sure if this is really practical.
Does this make sense? Have I missed something?
EDIT 2
Things get a bit more hairy when you consider that the code that we might be trying to kill could be untrusted:
We can't rely on "promises"; e.g. annotations on the untrusted code that it is either killable, or not killable.
We actually need to be able to stop the untrusted code from doing things that would make it unkillable ... according to the identified criteria.
I suspect that this would entail modifying JVM behaviour (e.g. implementing runtime restrictions what threads are allowed to lock or modify), or a full implementation of the Isolates JSR. That's beyond the scope of what I was considering as "fair game".
So lets rule the untrusted code case out for now. Or at least, acknowledge that malicious code can do things to render itself not safely killable, and put that problem to one side.
The lack of safety comes from the idea idea of critical sections
Take mutex
do some work, temporarily while we work our state is inconsistent
// all consistent now
Release mutex
If you blow away the thread and it happend to be in a critical section then the object is left in an inconsistent state, that means not safely usable from that point.
For it to be safe to kill the thread you need to understand the entire processing of whatever is being done in that thread, to know that there are no such critical sections in the code. If you are using library code, then you may not be able to see the source and know that it's safe. Even if it's safe today it may not be tomorrow.
(Very contrived) Example of possible unsafety. We have a linked list, it's not cyclic. All the algorithms are really zippy because we know it's not cyclic. During our critical section we temporarily introduce a cycle. We then get blown away before we emerge from the critical section. Now all the algorithms using the list loop forever. No library author would do that surely! How do you know? You cannot assume that code you use is well written.
In the example you point to, it's surely possible to write the requreid functionality in an interruptable way. More work, but possible to be safe.
I'll take a flyer: there is no documented subset of Objects and methods that can be used in cancellable threads, because no library author wants to make the guarantees.
Maybe there's something I don't know, but as java.sun.com said, it is unsafe because anything this thread is handling is in serious risk to be damaged. Other objects, connections, opened files... for obvious reasons, like "don't shut down your Word without saving first".
For this find(...) exemple, I don't really think it would be a catastrophe to simply kick it away with a sutiless .stop()...
A concrete example would probably help here. If anyone can suggest a good alternative to the following use of stop I'd be very interested. Re-writing java.util.regex to support interruption doesn't count.
import java.util.regex.*;
import java.util.*;
public class RegexInterruptTest {
private static class BadRegexException extends RuntimeException { }
final Thread mainThread = Thread.currentThread();
TimerTask interruptTask = new TimerTask() {
public void run() {
System.out.println("Stopping thread.");
// Doesn't work:
// mainThread.interrupt();
// Does work but is deprecated and nasty
mainThread.stop(new BadRegexException());
}
};
Timer interruptTimer = new Timer(true);
interruptTimer.schedule(interruptTask, 2000L);
String s = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab";
String exp = "(a+a+){1,100}";
Pattern p = Pattern.compile(exp);
Matcher m = p.matcher(s);
try {
System.out.println("Match: " + m.matches());
interruptTimer.cancel();
} catch(BadRegexException bre) {
System.out.println("Oooops");
} finally {
System.out.println("All over");
}
}
}
There are ways to use Thread.stop() relatively stable w/o leaking memory or file descriptors (FDs are exceptionally leak prone on *NIX) but you shall rely on it only if you are forced to manage 3rd party code. Never do use it to achieve the result if you can have control over the code itself.
If I use Thread.stop along w/ interrupt() and some more hacks stuff like adding custom logging handlers to re-throw the trapped ThreadDeath, adding unhandleExceltionHandler, running into your own ThreadGroup (sync over 'em), etc...
But that deserves an entire new topic.
But in this case it's the Java Designers telling you; and
they're more authorative on their language then either of us :)
Just a note: quite a few of them are pretty clueless
If my understanding is right, the problem has to do with synchronization locks not being released as the generated ThreadInterruptedException() propagates up the stack.
Taking that for granted, it's inherently unsafe because you can never know whether or not any "inner method call" you happened to be in at the very moment stop() was invoked and effectuated, was effectively holding some synchronization lock, and then what the java engineers say is, seemingly, unequivocally right.
What I personally don't understand is why it should be impossible to release any synchronization lock as this particular type of Exception propagates up the stack, thereby passing all the '}' method/synchronization block delimiters, which do cause any locks to be release for any other type of exception.
I have a server written in java, and if the administrator of that service wants a "cold shutdown", then it is simply NECESSARY to be able to stop all running activity no matter what. Consistency of any object's state is not a concern because all I'm trying to do is to EXIT. As fast as I can.
There is no safe way to kill a thread.
Neither there is a subset of situations where it is safe. Even if it is working 100% while testing on Windows, it may corrupt JVM process memory under Solaris or leak thread resources under Linux.
One should always remember that underneath the Java Thread there is a real, native, unsafe thread.
That native thread works with native, low-level, data and control structures. Killing it may leave those native data structures in an invalid state, without a way to recover.
There is no way for Java machine to take all possible consequences into account, as the thread may allocate/use resources not only within JVM process, but within the OS kernel as well.
In other words, if native thread library doesn't provide a safe way to kill() a thread, Java cannot provide any guarantees better than that. And all known to me native implementations state that killing thread is a dangerous business.
All forms of concurrency control can be provided by the Java synchronization primitives by constructing more complex concurrency controls that suit your problem.
The reasons for deprecation are clearly given in the link you provide. If you're willing to accept the reasons why, then feel free to use those features.
However, if you choose to use those features, you also accept that support for those features could stop at any time.
Edit: I'll reiterate the reason for deprecation as well as how to avoid them.
Since the only danger is that objects that can be referenced by the stoped thread could be corrupted, simply clone the String before you pass it to the Thread. If no shared objects exist, the threat of corrupted objects in the program outside the stoped Thread is no longer there.

Categories

Resources