好的,我一直在阅读 Jython 源代码并进行了一些测试。这是我发现的:
cleanup() 的作用:它负责未处理的资源,例如正在运行的线程和文件。
cleanup() 没有什么:以任何形式重置解释器的状态;保留导入的模块和定义的变量。
以下示例显示了这种行为:
示例 1
让我们导入一个模块,定义一个变量并打开一个文件。
PythonInterpreter py = new PythonInterpreter();
String code1 = "import sys;"
+ "a=45;"
+ "f = open('test.txt')";
String code2 = "print(sys.version_info);"
+ "print(a);"
+ "print(f.closed)";
// first execution
py.exec(code1);
py.exec(code2);
// second execution
py.cleanup();
py.exec(code2);
py.close()
输出
sys.version_info(major=2, minor=7, micro=2, releaselevel='final', serial=0)
45
False
------
sys.version_info(major=2, minor=7, micro=2, releaselevel='final', serial=0)
45
True
模块sys和变量a和f在清理后仍然存在相同的值,但是打开的文件被关闭了。
示例 2
为此,func 是一个慢速函数,大约需要 2 秒才能完成(比普通的 cleanup() 多)。
PythonInterpreter py = new PythonInterpreter();
String code3 = "from threading import Thread\n"
+ "def func():\n"
+ " print 'th start'\n"
+ " for i in range(0,20000000):\n"
+ " x=i\n"
+ " print 'th done'\n"
+ "th = Thread(target=func)\n"
+ "th.start()";
String code4 = "print th.isAlive()\n"
+ "th.join()";
// first execution
py.exec(code3);
py.exec(code4);
System.out.println("------");
// second execution
py.exec(code3);
py.cleanup();
py.exec(code4);
py.close();
输出:
th start
True
th done
------
th start
th done
False
在第一次执行中,主线程有足够的时间检查th是否存活并打印出来。在第二个中,它总是等待th 完成,这意味着cleanup() 在某个地方加入了线程。
结论
正如@mzjn 所指出的,close() 函数调用cleanup(),这是有道理的,所以您永远不需要在close() 之前调用cleanup()。唯一需要手动调用它的情况是,如果您想继续使用 PythonInterpreter 但需要关闭所有打开的文件并加入所有线程。