Reputation: 267
I have a CPP ThreadMgr that creates let's say 100 CPP Native threads (Thread Pool) on initialization.
Now, In Order to make JNI calls and interact with Java I have to attach a thread to JVM using AttachCurrentThread, and before terminating(normal or abrupt) these threads I have to DetachCurrentThread.
The approach I have is on creation I will attach all the native threads (100 in this case) to JVM and only when I'm terminating the thread I'll detach it from JVM.
Before building on this approach I want to list out the pros and cons to determine if it's a good approach to follow or not.
Some Pros/Cons I can think of,
Pros:
Cons:
There might be threads that will never make any JNI calls in their lifetime, still I'll be doing overhead calls of attaching/detaching them to JVM.
When a thread is attached to JVM, it has to allocate some resources for the attached thread, even if the attached thread is done with all the JNI calls, the resources will only free up once the thread is detached before termination.
Let me know if I missed any pros/cons of this approach and if this is a good approach to follow.
Upvotes: 0
Views: 182
Reputation: 180306
Pros:
- Attaching and detaching native threads to JVM have some performance overhead. By attaching once when creating the thread and detaching once before termination, we can minimize this overhead compared to attaching and detaching for every JNI call made within the thread.
True, but the importance of this gain depends on the workload. If the overhead of attaching and detaching is significant relative to the main work of a task itself, then in the context of that task it may be appropriate also to consider the overhead of using your thread pool to run it in the first place. Very quick tasks may be better run directly instead of via a thread pool.
Cons:
- There might be threads that will never make any JNI calls in their lifetime, still I'll be doing overhead calls of attaching/detaching them to JVM.
Yes. But if your thread pool were a reasonable size, and the overall work were enough to justify a thread pool in the first place, then that overhead is likely to be insignificant.
On the other hand, if it happens that none of the tasks submitted to the pool during its lifetime need a JVM, then there may be a significant resource savings to be had by not starting one at all.
- When a thread is attached to JVM, it has to allocate some resources for the attached thread, even if the attached thread is done with all the JNI calls, the resources will only free up once the thread is detached before termination.
True. In fact, resources allocated for a thread inside the JVM might not even be cleaned up immediately when the thread detaches. But how significant this is depends on a lot of factors, and of course, it scales with the number of threads that attach.
Overall, the pros and cons you present seem all to be focused on performance issues, but in general, performance depends on a lot of factors and is very difficult to predict. It needs to be measured, and if it is inadequate then effective tuning needs to be based on where the actual bottlenecks are measured to be.
I think you should be focusing more on higher-level design considerations, starting with whether a thread pool is the best choice for your needs at all. If you decide that a pool is indeed appropriate then do consider whether you really need or want to roll your own. I submit that you probably don't, and if you do not roll your own then that may well moot the question. In any case, focus first on good design, then write a good implementation.
Consider also that there may be viable hybrid approaches. For example, perhaps you want to maintain separate pools of JVM-attached threads and non-JVM-attached threads. Or maybe you want the pooled threads to adaptively attach at need, and then remain attached until the pool shuts down. Or maybe you want to turn it inside out, and use a thread pool managed by the JVM.
Upvotes: 0