2012-06-25 30 views
9

Tôi đã đọc các bài viết khác nhau về việc truyền các biến xung quanh bằng cách sử dụng RMI.là nó có thể vượt qua bằng cách tham chiếu trong RMI?

Một số người trong số họ nói rằng không thể chuyển biến theo tham chiếu trong RMI. ví dụ: this onethis one

Trong khi những người khác nói rằng điều đó là có thể. ví dụ: this one, this onethis one

bất kỳ ai có thể xóa điều này không? :)

Trả lời

5

Lưu ý quan trọng: nếu vượt qua bằng cách tham khảo phương tiện thay đổi giá trị tham số bên trong phương pháp và thay đổi biến ban đầu trong người gọi, bạn không thể. Nếu những gì bạn muốn làm là chuyển một bản sao của một tham chiếu đến một đối tượng, để cho phép phương thức tương tác với một số đối tượng của bạn ... có bạn có thể. Câu trả lời khám phá tùy chọn thứ hai đó.

Có. Nhưng nó phải là một đối tượng RMI. Trong trường hợp đó, một bản RMI sẽ được chuyển qua bản sao.

RMI qua đối số và trả lại giá trị theo hai cách: (! Nó có được từ xa nếu nó là một tài liệu tham khảo)

  1. sao chép toàn bộ đối tượng
  2. gửi một xa tham khảo.

mẫu

Guess chúng tôi có một dịch vụ. Đó là một đối tượng RMI, được xuất bản thông qua đăng ký RMI, vì vậy nó có thể truy cập được với các máy khách. Khách hàng có thể gọi một phương thức trên nó (để tạo ra một cái gì đó) và dịch vụ muốn trả về một tham chiếu đến đối tượng mới được tạo ra đó. Không phải là một bản sao được tuần tự hóa mà là một tham chiếu tới đối tượng được tạo trong không gian bộ nhớ máy chủ.

import java.rmi.Remote; 
import java.rmi.RemoteException; 

// normally published object 
public interface MyService extends Remote 
{ 
    // creates something and return a "handle" to it 
    public MyHandle createX(SomeSerializableObj param1) throws RemoteException; 
} 

// interface for object that the service will return a reference to... 
public interface MyHandle extends Remote 
{ 
    void doOne(); 
    void doTwo(); 
} 

Trong ví dụ này, bạn có thể:

Tạo một thực hiện MyService và xuất bản nó

Registry registry = LocateRegistry.createRegistry(port); 
MyService stub = (MyService) UnicastRemoteObject.exportObject(server, 0); 
registry.bind("myService", stub);` 

và sau đó, một số khách hàng RMI có thể nhận được một tham chiếu đến nó

Registry registry = LocateRegistry.getRegistry(server, port); 
MyService serv1 = (MyService) registry.lookup("myService"); 

và có tham chiếu đến đối tượng dịch vụ có thể lấy tham chiếu đến đối tượng RMI khác.

MyHandle handle1 = serv1.createX(...); 
handle1.doOne() 

Trong ví dụ này đối số phương pháp được đăng (nó phải là một lớp Serializable) trong khi đối tượng quay trở lại là một tham chiếu đến một đối tượng RMI được tạo trong máy chủ.

Việc triển khai createX (...) Có thể là:

public MyHandle createX(...) { 
    MyHandle handle = new MyHandleImpl(); // create an implementation 
    createdHandlers.add(handle); // add it to some structure (just a sample) 
    return handle; // return the implementation. RMI will send to client a RMI reference to this very instance 
} 
+0

cảm ơn :) nhưng tôi không nhận được câu trả lời của bạn: ( bạn có thể cung cấp ví dụ không? :) – MBZ

+0

Chắc chắn ... Tôi chưa có ví dụ nào tại thời điểm đó ... – helios

+1

@MBZ Nó dường như với tôi rằng anh ta đã đưa cho bạn một ví dụ, nhưng đây chỉ là một ví dụ khác của một tham chiếu được truyền theo giá trị. Nó không đi qua tham chiếu chút nào. Thay đổi giá trị của tham chiếu trong callee không thay đổi giá trị đó trong người gọi. Downvote. – EJP

3

Trong số tài liệu tham khảo của bạn:

(1) nói RMI không hỗ trợ vượt qua bằng cách tham khảo. Tôi đồng ý.

(2) cho biết RMI không hỗ trợ thông số vào-ra. Tôi đồng ý.

(3) chỉ trưng bày sự nhầm lẫn thông thường giữa việc truyền tham chiếu và tham chiếu truyền theo giá trị. RMI làm thứ hai, giống như phần còn lại của Java.

(4) không đúng.

(5) chỉ đơn giản là không mạch lạc. Không có tham chiếu pass-by-tham chiếu trong RMI.

Từ xa 'tham chiếu theo giá trị' của RMI về cơ bản không khác biệt ngữ nghĩa từ 'tham chiếu theo giá trị' của Java, ngoài các chế độ lỗi bổ sung có thể có.

Ý nghĩa của những gì bạn đã đọc là tài liệu tham khảo không xa, RMI đối số đối tượng và kết quả sẽ được thông qua bởi giá trị, qua Object Serialization, chứ không phải bằng cách lập luận của Java phương pháp tham chiếu theo giá trị đi qua.

0

Trong ý nghĩa xác thực nhất của từ no, bạn không thể.

Khi bạn vượt qua điều gì đó bằng cách "tham chiếu" những gì bạn đang thực sự làm là chuyển một con trỏ đến một vị trí trong bộ nhớ. Điều này hoạt động hoàn hảo khi người gọi và callee là cùng một quá trình, họ có quyền truy cập vào cùng một đống. Nhưng truyền tham chiếu bộ nhớ từ máy tính A đến máy tính B là vô nghĩa, A không thể truy cập bộ nhớ BS *. Tuy nhiên RMI cho phép bạn nhận được "tài liệu tham khảo" cho các đối tượng ở xa, nhưng điều này không hoàn toàn giống nhau, và nó phải được yêu cầu trước, chuyển một trong các đối tượng của bạn đến máy chủ sẽ dẫn đến một bản sao.

Trực tiếp từ miệng ngựa (http://www.oracle.com/technetwork/java/javase/tech/index-jsp-138781.html#3)

RMI sử dụng các đối tượng Java tiêu chuẩn cơ chế tuần tự hóa để truyền các đối tượng. Các đối số được tham chiếu đến các đối tượng từ xa được chuyển thành các tham chiếu từ xa. Nếu một đối số cho một phương thức là một kiểu nguyên thủy hoặc một đối tượng cục bộ (không phải từ xa), một bản sao sâu được truyền tới máy chủ. Giá trị trả lại được xử lý theo cùng một cách, nhưng theo một hướng khác. RMI cho phép bạn truyền và trả về đầy đủ các đồ thị đối tượng cho các đối tượng cục bộ và các tham chiếu đến các đối tượng ở xa.

Bạn có thể truyền xung quanh đối tượng từ xa bằng cách tham chiếu, nhưng bạn không thể chuyển đối tượng địa phương trở lại máy chủ dưới dạng tham chiếu.

* Về mặt kỹ thuật trong một số hệ thống bộ nhớ chia sẻ được phân phối trên quy mô lớn, bạn có thể, nhưng tôi nghi ngờ đó là những gì OP đang nói đến.

Các vấn đề liên quan