Get all threads that run with a specified Runnable - java

I have one Runnable that is used by more than one thread:
Runnable myRunnable = new MyWorker();
Thread one = new Thread(myRunnable);
Thread two = new Thread(myRunnable);
one.start();
two.start();
How can I get all threads that are created with myRunnable?
(Of course the example is simplified. I create new threads with myRunnable on several places in different classes.)
Use case (as requested): MyWorkerOfMyPage is a delayed worker that is bound to a page. If the user leaves this page (e.g. by navigating to another page) all threads that belong to MyWorkerOfMyPage should be killed ungracefully as their result is not needed anymore.

As already said best way is to track this yourself. This forces you to get a clear understanding of what you are doing. A good thing if you work with threads ... hmmm ... a good thing in every case ;).
But if you realy want to detect the threads you can use reflection with the Thread class to get the required information. First make the method "getThreads" accessible to get all running Threads, then make the field "target" accessible to get the runnables of the Threads.
Heres an example program (but I would advise against the usage in a real application. You should now what threads you are starting, it might harm compability with future JDKs, might harm portability ...):
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
Runnable myRunnable = new Runnable() {
#Override
public void run() {
try {
System.out.println("Start: " + Thread.currentThread().getName());
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
};
Thread one = new Thread(myRunnable);
Thread two = new Thread(myRunnable);
one.start();
two.start();
List<Thread> threads = getThreadsFor(myRunnable);
for (Thread thread : threads)
System.out.println("Found: " + thread.getName());
}
private static List<Thread> getThreadsFor(Runnable myRunnable) throws Exception {
Method getThreads = Thread.class.getDeclaredMethod("getThreads");
Field target = Thread.class.getDeclaredField("target");
target.setAccessible(true);
getThreads.setAccessible(true);
Thread[] threads = (Thread[]) getThreads.invoke(null);
List<Thread> result = new ArrayList<Thread>();
for (Thread thread : threads) {
Object runnable = target.get(thread);
if (runnable == myRunnable)
result.add(thread);
}
return result;
}
}

The best way to do this is to track this yourself. Use a global singleton for instance that launches the threads and track which ones you started.

Although my first thoughts are along #Bengt's lines, perhaps you could use Class.isAssignableFrom if you had a list of runnables and you just want to know which ones use your interface.
http://download.oracle.com/javase/6/docs/api/java/lang/Class.html

In Java there is no simple way to find all the places a object is referenced, its something you have to maintain a collection of yourself.
If you want to know this staticly you can Find Usages in your ide.
If you want to know this dynamically you can have the Runnable add the Thread to a collection (and remove it when finished)
Generally speaking, the developer should only create Threads deliberately. i.e. the Developer should know when he/she is creating thread and what those threads will be doing. Its not something you should be trying to track at runtime if you have a good design.

Related

HealthChecker for Java Process

I want to create a health checker, which will check the health of a java process. My process does a lot of things and is multi threaded. Various exceptions could be thrown, like Service / SQL / IO, etc. My plan is to call the HealthChecker to check for the process, from the catch block, in the individual threads. This will check for all the different healths, and in the case where there is any issue it will pause the threads, and log appropriately. There will be other processes which will read the logs by the process, and alert support to take appropriate actions.
Below is the general structure of the java process.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Schedular {
private static int numOfTasks = 10 ;
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
while(true){
for(int i=0;i<numOfTasks;i++){
service.execute(new Workers());
}
}
}
}
class Workers implements Runnable{
#Override
public void run() {
/*
* This can throw different exceptions , eg:
*/
try{
}catch(Exception e){
e.printStackTrace();
HealthChecker.checkHealth();
}
}
}
class HealthChecker{
public static void checkHealth() {
//Check health and then , log and pause all the threads
}
}
I am not able to figure out a way to pause all the threads. If there is a db exception I want all the threads to pause. I am requesting some suggestions.
You need a way to block the threads until some event occurs that allows the threads to continue. I see some major issues with the code:
1) The while(true) in your main thread might lead to a StackOverflowError. With each iteration of the while loop, you will add 10 more threads to the executor, and this will just continue unbounded.
2) There is no loop in your run() so that even if an exception is caught and we wait for the HealthCheck, the run() method would still exit. While a loop is not needed in your run() if you can constantly execute new Threads from your main thread to take the place of the terminated one, but that logic is not presently there in the main loop.
But setting those concerns aside here is one way to block worker threads until some event (presumably a HealthCheck all clear) occurs.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Schedular {
private static int numOfTasks = 10 ;
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
HealtchChecker hChecker = new HealthChecker();
for(int i=0;i<numOfTasks;i++){
service.execute(new Workers(hChecker));
}
}
}
class Workers implements Runnable{
private HealtchChecker hChecker;
public Workers(HealtchChecker hChecker){
this.hChecker = hChecker;
}
#Override
public void run() {
/*
* This can throw different exceptions , eg:
*/
while(true) {
try{
}catch (InterruptedException ie) {
throw ie;
}catch(Exception e){
e.printStackTrace();
HealthChecker.checkHealth();
}
}
}
}
class HealthChecker implements Runnable {
private final Semaphore semaphore = new Semaphore(1, true);
public void checkHealth() {
try {
semaphore.acquire();
} finally {
semaphore.release();
}
}
#Override
public void run(){
//code to check for errors that cause threads to pause.
if (inErrorState) {
semaphore.acquire();
} else {
semaphore.release();
}
}
}
A few things worth mentioning.
1) The main thread only creates 10 threads, versus an unbounded amount. You can adjust this as needed.
2) The Worker thread is long lived, meaning it will continue running even if it encounters Exceptions, except for an InterruptException.
3) HealthCheck is no longer a static object. it is instead a shared object.
4) HealthCheck is a runnable that can be executed in its own thread for monitoring for errors. I did not add the code to execute this thread.
5) HealCheck uses a Semaphore to cause the threads to block until the error state is cleared. I looked for other objects that can do this, like CountDownLatch or CyclicBarrier or Phaser, but this one came closest to giving us what we need to block all the threads from one point (the run() method).
Its not perfect but I think it gets you a little bit closer to what you want.
You're venturing pretty far afield from best practices, but you didn't ask about best practices for monitoring the health of threads - so I won't answer that question. Instead, I'll just answer the question you asked: how can I pause a set of threads managed by an ExecutorService?
Assuming that your Workers.run() will eventually end without intervention (in other words, it's not in an infinite loop - intentional or otherwise), the right thing to do is to call service.shutdown() (where service is your instance of ExecutorService). To do this, you can pass service in to HealthCheck.healthCheck() as a new parameter. Calling shutdown() will allow the currently-running threads to complete, then stop the executor.
If Workers.run() will not naturally complete, best practice says that you need to change your code such that it will. There is a Thread.stop() method you can call to halt the thread and a Thread.suspend() method you can call to suspend the thread. Both of these are double-bad ideas for you to use for two reasons:
They are Deprecated and will leave the Threads in a super-unhealthy state. You will have very difficult problems in the future if you use them.
You are using ExecutorService. That means you are delegating thread management to that class. If you go messing with the state of the Threads underneath ExecutorService, it can't manage the thread pool for you and, again, you will have very difficult problems in the future.

How to change my Thread implementation to use ExecutorService

I had been making a game, and was using Threads in my program to carry out tasks. So let me explain the scenario a bit. I have a BattleManager class which implements Runnable and keep looping in the battle queue for battles, if there are any.
#Override
public void run() {
while(serverRunning){
synchronized (battleQueue) {
for(Battle battle : battleQueue){
if(battle != null){
if (battle instanceof WildBattle) {
if(!((WildBattle) battle).isBattleOver()){
((WildBattle) battle).tryExecuteBattleTurn();
}else{
battleQueue.remove(battle);
battle = null;
}
}
}
}
}
try {
Thread.sleep(3);
} catch (InterruptedException e)
e.printStackTrace();
}
}
currentThread = null;
}
Then I check if battle is not over, and if not I try to execute the battle turn. Since there can be more than 100 battles running at the same time and there are complex calculations inside every battle, I inside WildBattle class spawn a child thread to execute the task, so that the battles run in parallel.
Here is the method which is invoked inside wild battle class, which spawns a new thread.
public void tryExecuteBattleTurn() {
if (!isBattleTurnRunning && battleThread == null) {
battleThread = new Thread(new Runnable() {
#Override
public void run() {
//long startTime = System.currentTimeMillis();
executeBattle();
battleLog.setBattleLog("");
battleThread = null;
//System.err.println("Total execution time : " +(System.currentTimeMillis() - startTime));
}
}, "Battle thread");
battleThread.start();
}
}
Now the main question is, I want to learn about executor service and I read at few places that it is always better to use executor service rather than spawning new child threads. How can I change this to use executor service.
I am not sure though. I am not a java expert and still learning the language so spare me if you see something is wrong, and please let me know if I can change anything to make it more efficient.
Let me know if you are not clear about anything.
I'll show you a basic example and you'll manage how to integrate it with your code
First you create ExecutorService somewhere in your application.
ExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_THREADS);
You should choose NUMBER_OF_THREADS based on your application needs. Threads are not created immediately - only when you submit a task to service and there are no available threads for it. If all NUMBER_OF_THREADS are busy, task will wait in queue until one of the threads will be able to handle it. ExecutorService will reuse threads, this will save time on thread instantiation and is a generally good concept to work with threads.
Then you manage how to access executor service from your battles. Then, when you need to perform an asynchronous work you submit task to service:
executorService.submit(new Runnable() {
#Override public void run() {
// your code here
}
}
If your application has a lifecycle and can be somehow shutdown, you'd like to shutdown ExecutorService as well. There are two options - shutdown() and shutdownNow(), first one waits for all current tasks to be executed, second one performs shutdown immediately and returns list of tasks that were not completed.
As was mentioned in comments, you should figure out how to preserve model state and organize thread synchronization based on your real situation.

Java threads scheduling

I have a MainClass, a Worker class and a Supervisor class. In MainClass i create 10 Worker classes and a Supervisor class that run in separate threads.
class MainClass {
public static void main(String args[]) {
for (int i=0; i<10 ;i++) {
Thread t = new Thread( new Worker());
t.start();
}
(new Thread(new Supervisor()).start();
}
.
class Worker extends Thread {
public void run() {
while(true) {
if(some_condition) {
//do stuff
} else {
// pause thread execution for undefined time.
}
}
}
}
.
class Supervisor extends Thread {
public void run() {
while(true) {
if(some_condition) {
// restart Workers thread that are paused.
}
// do other stuff
}
}
}
I don't know how to implement this, cause the conditions in every thread are independent from each other so i don't need to synchronize, so i can't use wait-notify.
I don't know how to implement this, cause the conditions in every thread are independent from each other so i don't need to synchronize, so i can't use wait-notify.
Sure you can.
The subtlety here is that presumably Supervisor doesn't actually know whether worker threads are really paused. (If it does, then the conditions are not independent.)
Since Supervisor doesn't know whether the threads are actually paused (by assumption), you have to design what you want to happen if it tries to unpause an already-unpaused thread.
a) Should an unpause do nothing?
b) Or should it immediately unpause the next time a worker tries to pause itself?
If the answer is (b), then you have to worry about thread safety. If the answer is (a), then you don't (unless you have some other data to pass between threads!)
Either way, you can still use wait and notify.
As per my understanding u want to create separate thread pools which consist of 10 workers or number as per your requirement.
As far as pools are concerned you can check for ThreadPoolExecutor in java.util.concurrent api. Internally ThreadPoolexecutor also creates worker Threads for running tasks.
Try reading ThreadPoolExecutor it might help you or please elaborate your question whats your ultimate objective you wish to achieve by this problem.

How to change a variable via a worker thread

Is there an elegant way to do that? Or it can always be avoided because one can use a better design patter?
import java.util.ArrayList;
import java.util.List;
public class ForTest {
List<String> ls = new ArrayList<String>();
public static void main(String[] args) {
ForTest forTest=new ForTest();
System.out.println(forTest.ls.size());
new Thread(new Worker(forTest.ls)).start();
//size() does not change at all
System.out.println(forTest.ls.size());
}
}
class Worker implements Runnable{
List<String> list;
public Worker(List<String> li) {
this.list = li;
}
public void run(){
this.list.add("newItem");
}
}
There are several issues with your code (in particular you use ArrayList which is not thread safe without proper synchronization).
But the most obvious one is that the second println statement is almost always going to be called before your run method has had a chance to be executed.
You need to make your main thread sleep() for a while. The size() is getting called before the new Thread gets a chance to update it.
new Thread(new Worker(forTest.ls)).start();
Thread.sleep(2000);
System.out.println(forTest.ls.size());
An even better way would be to join() on to the worker thread. This would make the main thread automatically wake up when the worker is finished.
Thread worker = new Thread(new Worker(forTest.ls));
worker.start();
worker.join();
System.out.println(forTest.ls.size());
In addition to that make use of a synchronized ArrayList to prevent a race condition if the List would be shared and modified by multiple threads.
List<String> ls = Collections.synchronizedList(new ArrayList<String>());
You seem to be missing the idea of Threading. Your code will not work because your worker has likely not updated ls by the time you print it. If you're using threading, the threads need to communicate state. This is all quite complex, I suggest you read the java tutorials on threading http://docs.oracle.com/javase/tutorial/essential/concurrency/
Please note that ArrayList is not synchronized, but Vector is. You cannot expect the worker to run just a moment after you started its thread. That's why the list size is not changed yet. I guess this is not your complete example, so it is difficult to help you. (If this was your complete example I would wonder why you bother implementing a multi-threaded solution.)
For knowing when the worker finished you could join the threads.
wait for the new thread to actually start running your code + make forTest final to be able to access it (also use a thread-safe collection - best non-synchronous a.k.a. non-blocking) e.g.
import java.util.Collection;
import java.util.concurrent.ConcurrentLinkedQueue;
public class ForTest {
Collection<String> ls = new ConcurrentLinkedQueue<String>();
public static void main(String[] args) throws InterruptedException {
final ForTest forTest = new ForTest();
System.out.println(forTest.ls.size());
int threads = 10;
for ( int i=0; i<threads; i++ ) {
new Thread(new Runnable() {
#Override
public void run() {
forTest.ls.add("newItem");
}
}).start();
}
Thread.sleep(1000);// wait for it !
System.out.println(forTest.ls.size()); // 10 unless your threads are really slow
}
}

Multithreading - Naming threads and handling exceptions

In java, what are the suggested ways to implement the two thread requirements
I would like the name a thread
I would like the parent (or main) thread know if there are any exceptions by this child thread.
For 2, I understand that having a future object would be a better approach. So to implement the above two requirements below is a code I came up with
class MyRunnable implements Runnable {
....
}
MyRunnable myRunnable = new MyRunnable ();
FutureTask futureTask = new FutureTask(myRunnable, null);
Thread myThread = new MyThread(futureTask, "processing-thread");
myThread.start();
try {
futureTask.get();
} catch (Exception e) {
throw new RuntimeException(e)
}
This seems to be a lot of code for simple stuff. Any better ways?
Note - Using executorService is not an option since I have threads which are not doing similar tasks. Also executorService accepts a thread name prefix instead of a thread name. I want to give each thread a unique name.
Using executorService is not an option since I have threads which are not doing similar tasks.
I don't see how this would matter.
Also executorService accepts a thread name prefix instead of a thread name. I want to give each thread a unique name.
So give each thread a name with a ThreadFactory. I have a class which I call a NamedThreadFactory.
I suspect what you would like the thread to do is reflect what the task is doing.
You can do this
ExecutorService es = Executors.newSingleThreadExecutor();
es.submit(new Runnable() {
public void run() {
Thread.currentThread().setName("Working on task A");
try {
System.out.println("Running: "+Thread.currentThread());
} finally {
Thread.currentThread().setName("parked worker thread");
}
}
});
es.shutdown();
prints
Running: Thread[Working on task A,5,main]
BTW There is no point starting a thread and immediately waiting for it to finish. You may as well use the current thread.
For the naming:
ThreadFactory myFactory = new ThreadFactory(){
#Override public Thread newThread( Runnable r ) {
return new Thread( r, getName() )
}
private int number = 0;
private String getName(){
return "MyThread_" + (number++);
}
}
There are other ways, too. This is the I like best, personnally.
---EDIT---
To give the thread completely different names, I would go another way:
One possibility would be to set the name inside the Runnable: See Peter's answer with one addition: instead of the fixed String, you could initialize a member variable of your Runnable implementation before starting the Thread.

Categories