I need help. For example I have such class.
public class ThreadTest {
public void runThreads() {
Thread t1 = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int i = 1;
System.out.println("Thread " + i);
});
Thread t2 = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int i = 2;
System.out.println("Thread " + i);
});
t1.start();
t2.start();
}
}
I run classVisitor for ThreadTest
. And I want to get the byte code which executes in first and second threads. Is there any way to do that? I think I should visit class Thread
and then visit method run
in it. But how can I do this from ThreadTest
?
You have to understand how lambdas are compiled. There is no point in analyzing the code of class java.lang.Thread
as its documentation already tells you what it will do, i.e. that it will invoke the run
method of the provided Runnable
instance, but that instance will be created at runtime by the LambdaMetaFactory
.
But your class ThreadTest
contains the actual code which will finally be invoked. It’s sitting in synthetic methods in this class. When you traverse the runThreads()
method you will encounter invokedynamic
instructions. The bsmArgs
parameter depends on the actual bootstrap method of the invokedynamic
instruction, so you have to look up its documentation to understand its meaning. You will learn that it contains a handle pointing to the (synthetic) target method (in your class). So you know that that method contains the code that will finally executed by the other thread.
In your case you will encounter two invokedynamic
instructions pointing to different synthetic methods representing the different code executed by the different threads.