如何使用可序列化对象和回调方法正确模拟 Java RMI 中的引用传递?

发布于 2025-01-08 13:40:16 字数 1348 浏览 0 评论 0原文

我有一个使用 java RMI 的分布式应用程序和一个实现 java.io.Serialized 的主对象(CoreApplication)。每分钟,这个主对象都会被发送到远程计算机并在该 JVM 的线程池上进行处理。由于它是异步的,因此处理对象时不会阻塞主计算机上的主线程。

当 CoreApplication 对象完成远程线程上的处理时,它会调用回调方法并被发送回主计算机。

这是远程计算机处理通过 RMI 和 sendJob 方法从主计算机调用的作业的一些代码。

public void sendJob(final CoreApplication aJob) throws RemoteException{
    Runnable r = new Runnable(){
        public void run(){
            try {
                WorkResponse wr = aJob.process();
                client.coreApplicationHandler(aJob,wr); 
            }catch(RemoteException e){}
        }
    };
    workQueue.execute(r);
}

您可以看到 client.coreApplicationHandler 是主服务器的回调方法,并将 CoreApplication 对象连同响应对象一起发送回来。

这是主机上的 coreApplicationHandler 方法代码

    public void coreApplicationHandler(CoreApplication j,WorkResponse wr){
        String ticker = j.getTickerSymbol();
        coreApplicationObjects.put(ticker, j);
        if(GlobalParameters.DEBUG_MODE){ 
            System.out.println("WORK RESPONSE IS "+wr.getMessage());
        }
    }

我的问题是,每次在回调方法上替换 CoreApplication 对象是确保它在发送的下一分钟是最新的最佳方法吗? CoreApplication 是流动的并且会发生变化,并且必须保留状态。我将其发送回主计算机,以便可以从中央位置监控它的状态。如果我有 100 个计算节点并且它们没有返回它们的对象,我认为跟踪它们会变得非常混乱。

到目前为止,它工作得很好,除非该作业在尝试发送另一个作业时尚未得到处理,并导致发送具有旧状态的过时对象(即与最后一分钟相同的对象)。如果这没有意义,请发表评论,我会尽力解释。

I have a distributed application using java RMI and a main object(CoreApplication) that implements java.io.Serializable. Every minute, this main object is sent to a remote computer and processed on that JVM's thread pool. Since it's asynchronous, the object is processed without blocking the main thread on the Master computer.

When the CoreApplication object is finished processing on the remote thread, it invokes a call back method and is sent back to the main computer.

Here is some code of the remote machine processing a job invoked from the Master computer via RMI and the sendJob method

public void sendJob(final CoreApplication aJob) throws RemoteException{
    Runnable r = new Runnable(){
        public void run(){
            try {
                WorkResponse wr = aJob.process();
                client.coreApplicationHandler(aJob,wr); 
            }catch(RemoteException e){}
        }
    };
    workQueue.execute(r);
}

You can see client.coreApplicationHandler is the callback method to the main server and sends the CoreApplication object back with it, along with a response object.

Here is the coreApplicationHandler method code on the main machine

    public void coreApplicationHandler(CoreApplication j,WorkResponse wr){
        String ticker = j.getTickerSymbol();
        coreApplicationObjects.put(ticker, j);
        if(GlobalParameters.DEBUG_MODE){ 
            System.out.println("WORK RESPONSE IS "+wr.getMessage());
        }
    }

My question is, is replacing the CoreApplication object each time on the call back method the best way to make sure it's up-to-date for the next minute it's sent? CoreApplication is fluid and changes and the state must be preserved. I am sending it back to the Master computer, so it's state can be monitored from a central location. If I had 100 computation nodes and they didn't return their objects, it would get really messy I think to keep track of them all.

It works pretty good so far unless the job isn't processed by the time it tries to send out another and results in sending a stale object with an old state (ie, the same object as the last minute). Please comment if this doesn't make sense and I will do my best to explain it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

荒岛晴空 2025-01-15 13:40:16

RMI 不是跨集群同步对象的方法。但有一些工具可以做到这一点。例如,查看 http://www.hazelcast.com/

如果您有一个计算机集群并且需要同步,那么您需要通过服务器工具或第三方工具使用集群。

我推荐榛子。它非常易于使用,并且允许使用快速 UDP 的本地集群或使用 TCP 套接字到 TCP 套接字的 WAN 集群。

例如 Hazelcast 会让你做这样的事情:

import com.hazelcast.core.MultiMap;
import com.hazelcast.core.Hazelcast;
import java.util.Collection;

// a live shared multimap shared across all cluster nodes
MultiMap<String, Order> mmCustomerOrders = Hazelcast.getMultiMap("customerOrders");

mmCustomerOrders.put("1", new Order ("iPhone", 340));

Thread.Sleep( 1000 );

Order order = (Order) mmCustomerOrders.get("1");

System.out.println( Order.quantity() ); // 340 ?? Nobody knows, it might have been changed

输出是什么?如果集群成员更改了地图中的项目“1”,那么您将自动获得该值。不再需要编码......

希望它有帮助

- 亚历克斯

RMI is not a way to synchronize objects across a cluster. But there are tools to do just that. Look at http://www.hazelcast.com/, for example.

If you have a cluster of computers and need synchronization then you need to use clustering via the server's tools or a third party tool.

I recommend hazelcast. It is very easy to use and will allow local clusters using fast UDP or WAN clusters using TCP socket to TCP socket.

For example Hazelcast will let you do something like this:

import com.hazelcast.core.MultiMap;
import com.hazelcast.core.Hazelcast;
import java.util.Collection;

// a live shared multimap shared across all cluster nodes
MultiMap<String, Order> mmCustomerOrders = Hazelcast.getMultiMap("customerOrders");

mmCustomerOrders.put("1", new Order ("iPhone", 340));

Thread.Sleep( 1000 );

Order order = (Order) mmCustomerOrders.get("1");

System.out.println( Order.quantity() ); // 340 ?? Nobody knows, it might have been changed

What is the output? If a cluster member changed the item "1" in the map, then you will get that value automagically. No more coding necessary….

Hope it helps

-Alex

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文