如何防止在从另一个线程进行静态调用时创建对象副本

时间:2019-07-09 08:31:21

标签: java multithreading static

我目前正在解决一个长期项目中的内存问题,并且遇到了一个特别耗费内存的问题。问题在于,一个类拥有一个非常大的静态数据结构,以及一个静态remoteSubscriber类。我们使用TimerTask定期在远程位置注册订户。

为此,将相关字段传递给计时器,该计时器将创建类ConnectionManager类的完整副本。这包括 massive 数据结构。

为了防止我们的数据需求量最大的对象两次,我想找到一种使用这些字段的方法,该方法不需要将整个父对象复制到新线程。想到RMI,但是还有其他选择吗?

以下是该问题的一些伪代码:

public class ConnectionManager{

private static volatile ConnectionManager INSTANCE=new ConnectionManager();
private BigFatStructure bigMama;
private RemoteSubscriber remoteSubscriber;


private ConnectionManager() {

    }

public void initConnection() {
   //initializes fields
}

private static void connect() {
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new KeepAliveTask(remoteSubscriber),SOMEVALUE,SOMEVALUE);
        try {
            registerSubscriber();
        } catch (DistributionException e) {
        }

    }

public static ConnectionManager getInstance() {

        if(INSTANCE==null){
            synchronized(ConnectionManager.class){
                if(INSTANCE==null){
                INSTANCE=new ConnectionManager();
                }
            }
        }
        return INSTANCE;
    }
}

public class KeepAliveTask extends TimerTask {
    private  RemoteSubscriber remoteSubscriber;

public KeepAliveTask(Subscriber remoteSubscriber){
        this.remoteSubscriber=remoteSubscriber;
    }

    @Override
    public void run() {
        if (ConnectionManager.getInstance().getRemoteSubscriber() != null) {
            try {
                try {
            IRemoteService service = MyProvider.getService();
            service.register(remoteSubscriber);
        } catch (Exception e) {
            throw new DistributionException(e);
        }
            } catch (DistributionException e) {
            }
        }
    }
}

防止新线程持有ConnectionManager的单独副本的最佳方法是什么?

谢谢!

编辑:更改了代码和说明以更好地反映更新后的状态

2 个答案:

答案 0 :(得分:1)

您可以使用单例模式来拥有一个唯一的对象。

https://www.javatpoint.com/singleton-design-pattern-in-java

看看Java设计模式,它们是解决特定问题/任务的成熟解决方案。

https://www.javatpoint.com/design-patterns-in-java

答案 1 :(得分:0)

我们已经解决了该问题。原因是类“ ConnectionManager”存在于2个程序包中,并且该程序的另一部分以某种方式处理了一个单独的对象。该对象以前曾用于其他功能,但由于它是不久前删除的,因此只需解雇加载另一个ConnectionManager的代码即可完全解决此问题。