Wednesday, February 15, 2023

How to do Inter process communication in Java? MemoryMapped File Example Tutorial

Hello guys, in the past, I have shown you how to do inter-thread communication in Java using wait-notify, and today, I will teach you how to do inter-process communication in Java. There are many ways to do inter-process communication in Java, you can use Sockets, both TCP and UDP, you can use RMI (Remote Method Invocation), you can use web services, or you can use memory-mapped file. The socket is the most common way of achieving inter-process communication if two processes are in two different hosts and connected via a network. RMI and WebService can also be used for similar purposes, but the last one, inter-process communication using memory-mapped files, is particularly useful if you are communicating with other processes in the same host, sharing the same memory and file system.

You can use a memory-mapped file to talk to another Java process or C/C++ process because they share the same memory. It is also the fastest way to share data between two processes, more rapid than using loopback sockets.

In a multi-core system, two processes can run on separate cores, and if you are really doing fast data sharing, you also need a mechanism to tell JVM that it's time to flush CPU cache, using a static volatile variable is an excellent way to say that, alternatively you can use Thread.sleep() to give some time to JVM to update CPU cache.

Btw, if you are serious about building a high-performance Java application then I also recommend you check out these Java Multithreading and Concurrency courses which is a great course for experienced Java programmers. You will learn tips and tricks to create highly concurrent and fast Java applications.




How to do Interprocess communication in Java? Example

Here is a code example of two processes communicating with each other using a Memory Mapped file in Java. 


Process 1 which is producing data :

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * Inter process communication in Java using memory mapped file
 *
 * @author WINDOWS 8
 */

public class Producer {

    public static void main(String args[]) throws IOException, InterruptedException {

        RandomAccessFile rd = new RandomAccessFile("C:/temp/mapped.txt", "rw");

        FileChannel fc = rd.getChannel();
        MappedByteBuffer mem = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1000);

        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
     
        for(int i=1; i            mem.put( (byte) i);
            System.out.println("Process 1 : " + (byte)i );
            Thread.sleep(1); // time to allow CPU cache refreshed
        }
    }
}

Output
Process 1: 1
Process 1: 2
Process 1 : 3
Process 1: 4
Process 1: 5
Process 1: 6
Process 1: 7
Process 1: 8
Process 1: 9

And here is a diagram that shows how this whole thing is working together:

How to do Inter process communication in Java? Example Tutorial


Process 2, which is consuming data


import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * Inter process communication in Java using memory mapped file
 *
 * @author WINDOWS 8
 */

public class Consumer {

    public static void main(String args[]) throws IOException {

        RandomAccessFile rd = new RandomAccessFile("C:/temp/mapped.txt", "r");

        FileChannel fc = rd.getChannel();
        MappedByteBuffer mem = fc.map(FileChannel.MapMode.READ_ONLY, 0, 1000);
     
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
     
     
        int value = mem.get();
        while(value != 0){
            System.out.println("Process 2 : " + value);
            value = mem.get();
        }
    }
}


Output
Process 2: 1
Process 2: 2
Process 2 : 3
Process 2: 4
Process 2: 5
Process 2: 6
Process 2: 7
Process 2: 8
Process 2: 9


That's all about how to do inter-process communication in Java. In this article, you have learned how to use a Memory-mapped file for inter-process communication in Java. This program not only teaches you how to do inter-process communication but also how to use the memory-mapped files in Java which can be used for fast read and write operations. Many Java programmers also use that as a cache in Java. 


Other Java Multithreading and Concurrency Articles you may like
  • The Complete Java Developer RoadMap (roadmap)
  • Top 5 Books to Master Concurrency in Java (books)
  • Difference between volatile, synchronized, and atomic variable in Java (answer)
  • 10 Java Multithreading and Concurrency Best Practices (article)
  • Top 50 Multithreading and Concurrency Questions in Java (questions)
  • 10 Courses to learn Java for Beginners (courses)
  • Difference between CyclicBarrier and CountDownLatch in Java? (answer)
  • How to avoid deadlock in Java? (answer)
  • Difference between Executor and ExecutorService in Java? (answer)
  • Understanding the flow of data and code in Java program (answer)
  • Is Java Concurrency in Practice still valid  (answer)
  • How to do inter-thread communication in Java using wait-notify? (answer)
  • 10 Tips to become a better Java Developer (tips)
  • Difference between ForkJoinPool and Executor Framework in Java(answer)
  • 5 Essential Skills to Crack Java Interviews (skills)
  • What is Happens Before in Java Concurrency? (answer)
  • 5 Courses to Learn Java Multithreading in-depth (courses)

Thanks for reading this article so far. If you like this article then please share it with your friends and colleagues. If you have any questions or feedback then please drop a note.

P. S. - If you are serious to improve your Java Multithreading and Concurrency Skills but looking for a free course to start with then I also suggest you check out this awesome free Java Multithreading course on Udemy. It's completely free and more than 100K Java programmers already benefited from it. All you need to do is create a free Udemy account and enroll in that course. 

9 comments:

  1. waiting for 10000 ms is a long time. how can a process notify the other as soon as it finishes?

    ReplyDelete
    Replies
    1. Just call the notifyAll() or notify() method, the 10000 ms wait here is for demonstration purpose. its not required in real world projects.

      Delete
  2. Hi, how to understand to this row: for(int i=1; i mem.put( (byte) i);

    Thank you, vladimir

    ReplyDelete
    Replies
    1. Hello Vladimir, looks like some formatting issue, did you try running the programmer, it should be something like i=1; i< mem.put((byte) i); i++)

      Delete
  3. Error in above code
    Working code is below

    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.nio.MappedByteBuffer;
    import java.nio.channels.FileChannel;

    public class Exp_3_Producer
    {
    public static void main(String args[]) throws IOException, InterruptedException
    {
    RandomAccessFile rd = new RandomAccessFile("C:/Data/TCET/Sem 8/DC/mapped.txt", "rw");
    FileChannel fc = rd.getChannel();
    MappedByteBuffer mem = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1000);
    try
    {
    Thread.sleep(10000);
    }
    catch (InterruptedException e)
    {
    e.printStackTrace();
    }

    for(int i=1; i < 10; i++)
    {
    mem.put( (byte) i);
    System.out.println("Process 1 : " + (byte)i );
    Thread.sleep(1); // time to allow CPU cache refreshed
    }
    }
    }

    ReplyDelete
    Replies
    1. Hey Anonymous, thx for comment, what was the error you are talking about? can you please explain bit more for readers?

      Delete
  4. Hi Javin,
    I have doubt related to synchronization between 2 or more process.
    Here, 2 more process are trying to access the same java function which is trying to update the value in text file. How can i create lock for that function, such that at 1 time only process can access the function.
    Thank you

    ReplyDelete
    Replies
    1. Hello Shiv, just make the method synchronized, this will ensure that only one thread can go inside the method at anytime, you can also put

      System.out.println("Going in" + Thread.getCurrentThread().getName()) and similar text at the end of method to confirm this behavior.

      All the best, if you face any issue, please chat the error here.

      Delete
  5. Thanks. Can you please explain what could happen without the "Thread.sleep(1);"?
    Can we use "mem.put" to write the whole buffer and only then sleep?
    1ms is enough because we just need to make sure there's a context switch?

    ReplyDelete

Feel free to comment, ask questions if you have any doubt.