Why is it impossible to run runnable in a thread?

As far as I understand from java.lang.Thread docs and other questions posted here on stackoverflow, for example, “ How do I access a Runnable object by Thread? ” And “ Get the current instance of Runnable ” it is impossible to get a reference to the Runnable object embedded in Thread .

The scenario where such an opportunity would be useful is to implement a method whose signature cannot be changed, because we redefine the method defined in another class or interface and require different operations depending on the type of Runnable built into the current Thread .

If we had, for example, the getRunnable method in the Thread class, we could do something like this:

 if (Thread.currentThread().getRunnable() instanceof Type1) { // do something... } else { // do something else... } 

This can also be useful in situations where we want to ensure that the operations contained in a method are performed only by certain threads, and not by others.

So, I was wondering if there is a specific reason why Java developers decided not to allow an instance of Runnable from Thread , or is this a missing function that is worth notifying? If you think that there is no reason for this choice, but you should not notify him of the missing function, what strategy would you use in the scenario described above?

+6
source share
3 answers

So, I was wondering if there is a specific reason why the Java developers decided not to allow the Runnable instance from the thread

It probably just wasn't required. Runnable itself should be able to identify its own class, so the idea that it needs to get this information is strange. It can also be protection so that other threads do not have access to a class running in another thread.

If you need access to the current Runnable from other parts of your application, I would recommend using ThreadLocal<Runnable> . In your run() method, you can set it and then get in other classes. However, you need to host ThreadLocal somewhere on a global scale.

You can also process the current stack trace to determine the Runnable class, which is an even more hacker, but it will work.

+11
source

There are several approaches you can take to get around this:

Save the mapping of your Runnable to Thread , which executes them (either using Map<Thread, Runnable> , or using ThreadLocal<Runnable> )
Use reflection to access Runnable from Thread :

 private static final Field target; static { Field f = null; try { f = Thread.class.getDeclaredField("target"); f.setAccessible(true); } catch (NoSuchFieldException e) { // might happen in a different version of Java (works in Java 7) e.printStackTrace(); } target = f; } public static Runnable getTarget(Thread t) { try { return (Runnable) target.get(t); } catch (IllegalAccessException e) { // shouldn't happen, we already made the field accessible when we created it e.printStackTrace(); } return null; } 
+5
source

There is an indirect method that can help, you can get a stack trace.

 StackTraceElement[] stackTraceElement = thread.getStackTrace(); for(StackTraceElement e :stackTraceElement){ System.out.println("Trace "+e.getClassName()); } 

Exit:

Java.lang.thread trace

Trace com.emc.multithreading.RunnableDemo

Java.lang.thread trace

0
source

Source: https://habr.com/ru/post/914914/


All Articles