JR Virtual machines
Until now, we've always had concurrent program working in one virtual machines, but JR provides ways to declare several virtual machines on several different physical machines. A JR Virtual Machine contains a Java Virtual Machine and a layer for the JR language. Once you created some virtual machines, you can specify where an object will be created with a variant of the new operator. After that, almost all the development is transparent. By example, a send operation on an operation serviced by an other virtual machine is exactly the same as if there is only one virtual machine. You can do exactly the same thing. We'll see that there is some differences, but it's really easy.
An important thing to remember is that all the virtual machines created contains the static part of the application. So all the static part is local to the virtual machines. This can cause really difficult bug to solve if we don't take care.
So, now that we know the basis of the virtual machines, let's create a new virtual machine :
vm vm1 = new vm();
That will create a new virtual machine, named vm1, on the same physical machine where the code is executed. You can also choose to create a virtual machine on an other machine :
vm vm2 = new wm() on "192.168.1.200"; //IP Adresse of the machine vm vm3 = new wm() on "pc12"; //Name of the machine vm vm4 = new vm() on vm3; //The machine where vm3 is located
To create a virtual machine on an other machine, you need to right to connect to that computer with ssh or csh without any password. For more informations, the best is to read the official installation guide.
JR provide no way to destroy a virtual machine. Like any other objects, a vm became garbage collected when there is no reference to it and when the virtual machine is idle (all the processes are over or blocked).
If you want to place an object on a virtual machine, you must define it with the remote keyword :
remote Person person = new remote Person();
By default, the object is created on the same virtual machine where the code is executed, but you can put it in an other virtual machines :
remote Person person = new remote Person() on vm1;
You can also combine the creation of virtual machine and remote objects in one line :
remote Person person = new remote Person() on new vm() on "localhost";
Note that the class of any remote object must be declared public.
When working with remote objects, you have access to two new predefined fields :
- this.remote : Return the remote reference of the current object
- vm.thisvm : Return the vm in which the current object has been created
When you work with a single virtual machine, the parameter are always passed by value, but when you're working with remote references and several virtual machines, you cannot pass the objects by value, instead, a copy of the object is created and passed to the other virtual machines (JR use RMI and serialization to achieve that). So all the objects you pass to others virtual machines must be declared Serializable to pass through the virtual machines.
There is also others aspects that is interesting to know about working with several virtual machines. First of all, the System.out and System.int streams are inherited from the initial virtual machine. So you can see that the order is not always deterministic depending on the fact on the synchronization of the different prints. The first virtual machine begin the execution in the execution directory but the other virtual machines begins the execution in the user home directory.
Let's finish with a little example. By example, if we take the problem of consumer/producer we solved with Asynchronous Message Passing and we create the producer and consumer in different virtual machines, that will give us something like this :
class ProducerConsumer { private static final int N = 12; //Number of producers and consumers private static op void deposit(String); //The channel public static void main(String... args){ vm vmConsumer = new vm(); vm vmProducer = new vm(); for(int i = 0; i < N; i++){ new remote Consumer() on vmConsumer; new remote Producer() on vmProducer; } } public static class Consumer { private static process Consumer { String data; receive deposit(data); System.out.println("Consumer " + data); } } public static class Producer { private static process Producer { send deposit("Producer"); } }
All the consumer are created on a specified virtual machine and the producer in an other virtual machine. Here I create the two virtual machines in the same computer, but you can distribute them along several computers.
Here we are ! That post will be the last of the JR set of posts.
Comments
Comments powered by Disqus