我正在为Java 6 *1开发变换器,它执行一种部分评估,但为了简单起见,我们考虑Java程序的抽象语法树解释.
如何Thread
通过解释程序模拟行为?
目前,我想到了以下几点:
AstInterpreter应该实现java.lang.Runnable
.它还应该重写java.lang.Thread
(或其子类)的每个new-instance-expression,用新的AstInterpreter实例替换Thread
's target(java.lang.Runnable
):
编辑:提供更复杂的示例.
编辑2:备注1.
目标计划:
class PrintDemo { public void printCount(){ try { for(int i = 5; i > 0; i--) { System.out.println("Counter --- " + i ); } } catch (Exception e) { System.out.println("Thread interrupted."); } } } class ThreadDemo extends Thread { private Thread t; private String threadName; PrintDemo PD; ThreadDemo( String name, PrintDemo pd){ threadName = name; PD = pd; } public void run() { synchronized(PD) { PD.printCount(); } System.out.println("Thread " + threadName + " exiting."); } public void start () { System.out.println("Starting " + threadName ); if (t == null) { t = new Thread (this, threadName); t.start (); } } } public class TestThread { public static void main(String args[]) { PrintDemo PD = new PrintDemo(); ThreadDemo T1 = new ThreadDemo( "Thread - 1 ", PD ); ThreadDemo T2 = new ThreadDemo( "Thread - 2 ", PD ); T1.start(); T2.start(); // wait for threads to end try { T1.join(); T2.join(); } catch( Exception e) { System.out.println("Interrupted"); } } }
程序1(ThreadTest - 解释字节码):
new Thread( new Runnable() { public void run(){ ThreadTest.main(new String[0]); } });
程序2(ThreadTest - AST解释):
final com.sun.source.tree.Tree tree = parse("ThreadTest.java"); new Thread( new AstInterpreter() { public void run(){ interpret( tree ); } public void interpret(com.sun.source.tree.Tree javaExpression){ //... } });
生成的程序2是否正确模拟了线程的初始程序1的行为?
1)目前,source=8 / target=8
计划被接受.
我看到两个选择:
选项1:JVM线程.每次解释的程序调用Thread.start时,您也调用Thread.start并使用另一个解释器启动另一个线程.这很简单,使您不必执行锁和其他操作,但您可以减少控制.
选项2:模拟线程.类似于在单处理器上实现多任务处理 - 使用时间切片.您必须在解释器中实现锁定和休眠,并跟踪模拟的线程以了解哪些线程已准备好运行,哪些线程已完成,哪些线程已被阻止等.
您可以执行一个线程的指令,直到它阻塞或经过一段时间或达到一些指令计数,然后找到另一个可能现在运行的线程并切换到运行该线程.在操作系统的上下文中,这称为进程调度 - 您可能希望研究此主题以获取灵感.