I have created a dedicated thread pool to handle specific HTTP requests in Glassfish v3. I would like to get the number of inactive threads (free- not running) at any given point of time as I need to throttle the HTTP requests depending on the availability of worker threads. Is there a exposed API to get this? I don't want to submit the request to the thread pool unless threads are available.
To answer your question: As per best of my knowledge there is so no such API which can give you handy details you require, so I think you have to compute it yourself.
For solution part: java.lang.management package should help you.
java.lang.management.ManagementFactory
The ManagementFactory class is a factory class for getting managed beans for the Java platform.
You can consider using ManagementFactory which lets you get details from the JVM through exposed Java managed beans. For your case, you can use ThreadMXBean which will let you get all JVM thread information.
java.lang.management.ThreadMXBean
The management interface for the thread system of the Java virtual machine.
Read ThreadMXBean documentation and API thoroughly to understand it well, and I think in the end you can use java.lang.management.ThreadInfo object to get all the info you need.
java.lang.management.ThreadInfo
java.lang.management.ThreadInfo gets you a lot of Thread details as listed below. I don't think any other Java class can give this much info about Thread.
Thread ID.
Name of the thread.
Thread state.
The object upon which the thread is blocked due to:
waiting to enter a synchronization block/method, or
waiting to be notified in a Object.wait method, or
parking due to a LockSupport.park call.
The ID of the thread that owns the object that the thread is blocked.
Stack trace of the thread.
List of object monitors locked by the thread.
List of ownable synchronizers locked by the thread.
Below is a sample I have created for you, please note this is to get you started and a full-fledged solution cannot be provided, so please do more research about it, but I think would be helpful.
I am getting all thread states and printing them, so you can do IF-ELSE and then prepare a list of something based on state etc. and then take necessary action.
Hope this helps!
private static void getThreadInfo() {
System.out.println("Started");
ThreadMXBean managementFactory = ManagementFactory.getThreadMXBean();
long threadIds[] = managementFactory.getAllThreadIds();
for (int i = 0; i < threadIds.length; i++) {
ThreadInfo info = managementFactory.getThreadInfo(threadIds[i]);
System.out.println("Thread name = " + info.getThreadName() + " Thread id = " + info.getThreadId() + " Thread state = " + info.getThreadState());
}
System.out.println("#############");
System.out.println(Thread.currentThread().getAllStackTraces());
}
Output:
Started
Thread name = Attach Listener Thread id = 5 Thread state = RUNNABLE
Thread name = Signal Dispatcher Thread id = 4 Thread state = RUNNABLE
Thread name = Finalizer Thread id = 3 Thread state = WAITING
Thread name = Reference Handler Thread id = 2 Thread state = WAITING
Thread name = main Thread id = 1 Thread state = RUNNABLE
#############
{Thread[Finalizer,8,system]=[Ljava.lang.StackTraceElement;#1748ba4, Thread[Attach Listener,5,system]=[Ljava.lang.StackTraceElement;#7bd86d, Thread[main,5,main]=[Ljava.lang.StackTraceElement;#bdff3b, Thread[Reference Handler,10,system]=[Ljava.lang.StackTraceElement;#1bf8a41, Thread[Signal Dispatcher,9,system]=[Ljava.lang.StackTraceElement;#dd841}
Related
I'm developing an Android App in Java. I used a lot of library: firebase crashlytics, SQLCipher, ButterKnife etc.. The problem is: when I run the app from Android Studio, I notice the app still remain active as process, even if I close all activities. I know that there are some thread that works on background.. but I don't know how to check which thread is active, and more important, what does it do. Any idea about?
You can get what state a thread is in by using the getState() method which returns an Enum of Thread.States. A thread can only be in one of the following states at a given point in time.
NEW A Fresh thread that has not yet started to execute.
RUNNABLE A thread that is executing in the Java virtual machine.
BLOCKED A thread that is blocked waiting for a monitor lock.
WAITING A thread that is wating to be notified by another thread.
TIMED_WAITING A thread that is wating to be notified by another thread for a specific amount of time.
TERMINATED A thread whos run method has ended.
Thread t = new Thread();
Thread.State e = t.getState();
Thread.State[] ts = e.values();
for(int i = 0; i < ts.length; i++){
System.out.println(ts[i]);
}
To kill the thread , u can do this :
myService.getThread().interrupt();
NOTE : the method Thread.stop() is deprecated
EDIT : : try this
public void stopThread(){
if(myService.getThread()!=null){
myService.getThread().interrupt();
myService.setThread(null);
}
}
sorry for the long edit,
I am trying to download 100k urls and I started to download using executor service as below,
ExecutorService executorService = Executors.newFixedThreadPool(100);
for (int i = 0; i < list.size(); i++) {
try {
Callable callable = new Callable() {
public List<String> call() throws Exception {
//http connection
}
};
Future future = executorService.submit(callable);
but the above method is downloading the data only one url at a time..
and so I tried to create daemon threads (as shown below) and this method created muliple download connections (as expected) ..
for(int i=0; i<10; i++) {
Thread t = new Thread("loadtest " + i);
t.setDaemon(true);
t.start();
}
while(true) {
boolean flag = true;
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for(Thread t : threads) {
if(t.isDaemon() && t.getName().startsWith("loadtest")) {
flag = false;
break;
}
}
if(flag)
break;
Thread.sleep(5000);
}
Can the same method be used for load testing on servers ?
Any other suggestions of how load testing can be done will also be of great help..
Thanks in advance !
I will hazard a guess that your ExecutorService is not working because you are calling get() on the Future instances it returns inside your loop. This mistake will indeed cause your processing to be serialized as if you had only one thread, because another task isn't submitted until the first completes.
If you really need to use Callable, don't get() the result until you are ready to block for some indefinite time as the tasks complete—and they can't complete if they haven't been submitted yet. For downloading URLs, it would be better to use Runnable, where the main thread submits URLs and then forgets about the task; the task can independently complete processing of its URL.
If you produce new tasks quickly, there's a chance you could queue up so many that you run out of memory. In that case, you can use a bounded queue and set up an appropriate rejection handler using ThreadPoolExecutor directly.
A daemon thread is a thread which does not prevent JVM to exits when all other thread finished.
I believe if you want to wait for your main thread until the time daemon threads not finished then I suggest not to use daemon thread as it is supposed not be used for that use case. You can use Thread#join to wait for your main thread.
for(int i=0; i<10; i++) {
Thread t = new Thread("loadtest " + i);
t.setDaemon(true);
t.start();
t.join(); // main or parent thread will wait util the child thread finished
}
I believe in your use case you should use normal thread instead of daemon.
Load testing is not only about "hammering" your server with requests, well-behaved load test needs to represent real user using real browser with all associated stuff like:
headers
cookies
cache
handling embedded resources (images, scripts, styles, fonts)
So I would recommend using a specialized load testing tool which are capable of representing real user as close as possible and automatically taking care of aforementioned points. Also normally the load testing tools allow you to set rendezvous points and provide a lot of metrics and charts so you will be able to see connect time, network latency, throughput, correlate increasing load with increasing response time/number of errors, etc.
I have a program where many threads post their requests to a PriorityQueue.
Later, they wait for a response from ConcurrentSkipListMap. There is ONE thread that publishes answers to the ConcurrentSkipListMap.
The following lines of code illustrate this :
At program init
PriorityQueue<Request> requests = new PriorityQueue<Request>();
ConcurrentSkipListMap<Long, Reponse> responsesReceived = new ConcurrentSkipListMap<Long, Reponse>();
In a caller thread
// Send request ...
Request r = ... // Elaborate the request
requests.add(r);
// ... then wait for an answer
Long id = r.getId();
while (responsesReceived.containsKey(id) == false) {
synchronized (responsesReceived) {
responsesReceived.wait();
}
}
Answer a = responsesReceived.take(id);
// Do other things ...
In THE response handler thread
// Wait for a remote answer
Answer answer = ...;
// Once received publish it in ConcurrentSkipListMap
responsesReceived.put(answer.getRequestId(), answer);
synchronized (responsesReceived) {
responsesReceived.notify();
}
// Go back and wait for a new answer...
QUESTION
Is it safe to synchronize caller threads and response handler thread on the ConcurrentSkipListMap ?
Should I rather use a Lock for the synchronization ?
Should I use a HashMap of locks (HashMap<Long,Object>) ?
I'm pretty new with the java.util.concurrent API and I have some doubts...
With synchronized/wait/notify, you can use any object as lock. As for submitting jobs to a queue and waiting for their results, take a look at ExcutorService, Future, and CompletionService.
While this can work, it may not be the clearest way to represent what you are doing. I would add a separate "lock" object for such notifications.
Note: I would use notifyAll() unless you only ever have one waiting thread.
I have two requests in tomcat. One HTTP request will create a thread. Client can use a new HTTP request to terminate the same thread.
Is it possible to do that? If possible how?
Oh please, don't spawn unmanaged threads yourself in a Java EE application. Use an Executor with a fixed thread pool. Use Callable as tasks and use Future as future results.
Create one on application's startup (e.g. in ServletContextListener or servlet's init()).
ExecutorService executor = Executors.newFixedThreadPool(10); // Pool of 10 threads.
On first request, submit a task to it, get the Future result. The below example assumes that it's of type String and that Task is a Callable<String>:
Future<String> result = executor.submit(new Task());
Store this in the session:
request.getSession().setAttribute("result", result);
On any subsequent request in the same session, you could get it from the session and check if it's done or not and if necessary cancel it.
Future<String> result = (Future<String>) request.getSession().getAttribute("result");
if (result != null) {
if (!result.isDone() && userWantsToCancel) {
result.cancel();
}
}
See also:
Java concurrency tutorial
Yes it is possible under certain conditions:
Your Thread should be stoppable. Either by checking a flag in a loop, interrupting the Thread if it is sleeping, etc... Some explanations can be found here
You could use the session object to store the Thread and find it back when the second requests comes in. This requires that the client maintains the session (through a cookie or a request parameter, ...). There other alternatives to that.
yes it is possible
see http://oreilly.com/catalog/jservlet/chapter/ch03.html servlet life cycle
see servlet with thread
see request
Is there a way for a thread that starts a new thread to wait until the thread it started has stopped? I was thinking about using locked, but then if the thread crashes, the lock will never get release.
so when my program calls
cTurnCardOvrerConnection thread = new cTurnCardOvrerConnection("thread3", connection, mPlayerList, mPlayersMessages, lBoard);
will it wait until the thread is finished?
mPlayerList.WaitForAllPlayers();
do
{
do
{
r=GetClient();
switch(r)
{
case 0: return; // exitvon a very bad error
}
} while(r==2); // loop if it was a timeout wait for this thread to terminate.
cTurnCardOvrerConnection thread = new cTurnCardOvrerConnection("thread3", connection, mPlayerList, mPlayersMessages, lBoard);
if ( CheckTimeStamp())
break;
} while( mPlayerList.AllPlayersFinished()==false);
you can just use Thread.join().
of course, if the primary thread is just launching the secondary thread and then waiting for it to finish, there's really no use for the secondary thread (just do the work on the primary thread).
Try using a CountDownLatch.