如何通过两个不同的java进程创建一个类的单个实例

如何通过两个不同的java进程创建一个类的单个实例,java,unix,map,jar,Java,Unix,Map,Jar,我有一个类(MapLoader),用于加载地图 public class MapLoader{ statci Map aMap; static{ //does some processing to load this map } 此映射正由两个并行运行的不同作业使用。这些作业是unix批处理作业,它调用两个不同的jar文件 Jar 1: public class ABC{ public static void main(String args[]){ //uses MapLoader.aMa

我有一个类(MapLoader),用于加载地图

public class MapLoader{
statci Map aMap;
static{
 //does some processing to load this map
}
此映射正由两个并行运行的不同作业使用。这些作业是unix批处理作业,它调用两个不同的jar文件

Jar 1:
public class ABC{
public static void main(String args[]){
//uses MapLoader.aMap

}

Jar 2:
public class XYZ{
public static void main(String args[]){
//uses MapLoader.aMap

}
这些jar文件使用类MapLoader的映射

有没有办法两个进程只创建一个MapLoader实例。请建议


**请忽略java语法(如果有的话),我只是编写了解释我的问题的代码。

将您的MapLoader作为singleton类:

    private static MapLoader ml;
    public static MapLoader create ()

       {
           if (ml==null)
           {
              ml=new MapLoader ();
           }
           return (ml);
       }
创建一个新类,在其中创建MapLoader的一个实例:

    class OneInstance
       {
         public static returnOneInstance()
           {
               MapLoader mapLoader = MapLoader.create();
           };

现在,在ABC和XYZ类中扩展OneInstance类,那么它应该可以解决您的问题。

这将比您希望的困难得多

如果您希望以这种方式共享对象,那么最好的方法是使用线程而不是进程。在线程之间安排时间要比在两个Java进程之间安排IPC更容易

如果您必须使用两个不同的过程,那么您将不得不执行IPC。两个Java进程不能共享内存(某些JNI角落案例除外)。这就给您留下了诸如RMI、命名管道、共享文件、套接字等方法

此映射正由两个并行运行的不同作业使用

…通过这两个过程

你使用的是操作系统意义上的“进程”,对吗?不,您不能像那样在JVM实例之间共享对象


这听起来像是一个共享缓存,因此您最好使用Memcached,让第一个进程加载“lock”,然后初始化它。

并发初始化的一种模式是枚举。另一个是内部类(因为它保证在第一次使用时加载内部类)

由于不能再使用静态字段,因此必须调整使用方法

public enum MapLoader {

     INSTANCE;

     public Map aMap;
     {
         //does some processing to load this map
         aMap = new ConcurrentHashMap();
     }
}

volatile aMap = MapLoader.INSTANCE.aMap;
这将创建一个单例。我个人通常将共享实例传递给它们的构造函数中的每个线程,或者依赖某个容器(如在web应用程序中)来提供单实例

将字段
volatile
放在线程中可以确保它不仅被复制到线程中,而且在每次访问时都会被更新


ConcurrentHashMap确保了线程安全修改。

您可以通过将MapLoader作为singleton类来实现这一点

public class MapLoader {

    private static MapLoader map;



    public static MapLoader getInstance(){
        if(map== null){
            map= new MapLoader ();
        }
        return map;
    }
}
也请访问此链接


我们使用本地RMI服务器做了类似的事情,该服务器提供了常用缓存的集中实例。您可以对普通的
套接字
s执行类似的操作,但是您必须编写一个协议来与
映射加载器
交互,而不是试图通过网络对其进行序列化,因为这样你就有了一个单独的实例…在单独的进程中运行这些主进程的需求有多大?如果你是说从内存的角度来看只有一个实例是不可能的,但是对于类的内容,你可以使用Redis在VM之间共享内容,这是一个在内存中的解决方案,它是在两个不同进程中工作的东西之后的超级快速OP…这是一个singletonMemcached的奇怪例子!现在这是核武器行动的蚊子!这是一个相对薄的“DB,而且感觉它适合用例。若Map实际上是从DB中存储1M个键值对,那个么Memcached实际上是一个非常明智的选择。如果我们有两个共同的价值观,那就有点傻了;但是有1个代表的用户3671193有多大机会,谁不知道两个Java进程不能共享内存?有1M+个键值对?@Kong:我知道两个Java进程不能共享内存。但我想试一试。可能是像你这样聪明的人找到了办法-D@King:如果系统上有可用的库,则可以使用JNI来执行此操作
sys/shm.h
调用,基本上是。再次调用;OP正在寻找一个在两个进程之间执行此操作的解决方案。我不理解您的解决方案。我不需要静电场。我只希望两个进程(每个进程有8个线程)只使用一个实例。请详细说明您的解决方案。@user3671193做到了这一点,但恐怕一个好的教程比这里的任何答案都更有启发性。不幸的是,我也需要搜索一个链接。真的!第三次;OP正在寻找在两个进程之间执行此操作的解决方案@孔:有很多方法,我放了一些链接以获取更多信息。那么,如果第一个代码片段不能解决OP的问题,为什么要使用它呢?@Engineer:谢谢你的帮助。这有助于:-)