我的问题是我正在开发一个项目,要求我运行多个具有许多静态属性/变量的代码的实例,这会导致所有实例共享这些资源,并且崩溃。如果我创建一个.jar文件并通过在windows中运行.jar多次打开它,我可以运行这个其他人的程序的多个实例,但是在我的代码中多次运行调用“main”方法(这是什么我需要这样做不会起作用。
我考虑过创建一个.jar并使用Runtime.getRuntime().exec( "myprog.jar" );
多次调用该程序,但这对我不起作用,因为我必须将我的对象实例传递给这个新程序而且我不知道我认为这个解决方案可以实现这一点。
PS:This is also posted in the Sun forums,所以我会发布我在这里的答案,或者我在这里得到的答案,一旦我解决这个问题,我自然会得到适当的信用= P。
答案 0 :(得分:8)
请记住,Java中的静态元素仅在类加载器(层次结构)的上下文中是唯一的;一个类由Juple {classloader,classname}在JVM中唯一标识。
您需要实例化隔离的类加载器并使用该类加载器加载jar。每个加载的类(以及因此statis元素)在类加载器中都是唯一的,不会相互干扰。
答案 1 :(得分:2)
我说你有三种选择:
重构遗留应用程序,使其不使用静态属性。如果你能做到这一点,从长远来看,这可能是最好的解决方案。
继续在单独的JVM中启动旧应用程序的方法。您可以通过多种方式将对象(副本)传递给另一个JVM。例如,您可以序列化它们并通过子进程输入流传递它们。或者你可以将它们串化并将它们作为参数传递。在任何一种情况下,您都需要创建自己的“主”类/方法,以便在调用遗留应用程序之前处理传递的对象。
我认为您应该能够使用classloader magic在每次运行时动态加载旧应用程序的新副本。如果每次都创建一个新的类加载器,您应该使用一组单独的静态来获取旧应用程序类的新副本。但是,您必须确保遗留应用程序不在主类路径上。这种方法的问题在于它很昂贵,并且您可能会造成内存泄漏。
答案 2 :(得分:0)
描述有点令人困惑。
如果多次运行代码,则运行多个独立进程,每个进程都在自己的JVM中运行。他们无法实际共享静态字段的值。 Java不允许您直接在多个VM之间共享内存。
您能详细说明(理想情况下是示例和代码)定义属性的内容以及您获得的失败类型?这可能与它们是静态的完全无关。
特别是,您的共享资源究竟是什么意思?您的计划共享哪些资源?
答案 3 :(得分:0)
已经建议采用正确的方法 - 使用自定义ClassLoader
。另一件事我想到了,这可能看起来很难看,但可能会做,而且是一种更加面向对象的方法。
遗留代码用于其操作,并且它错误地使用static
而不是实例变量。您可以使用继承和反射来解决这个问题:
然后开始使用您的类的实例,而不是遗留的实例。这样你就可以模拟正确的行为。 请记住,这不是线程安全的。