Search code examples
javamultithreadingbytecode

How get code which executes in another thread with ASM?


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?


Solution

  • 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.