Java 进程间通讯的几种方式
Java 面试 About 3,343 wordsIPC
进程间通讯:InterProcess Communication。不同进程间的数据读写。
Socket 方式
如HTTP、TCP、RPC等可以实现直接的数据交换。
MQ 方式
如RabbitMQ、RocketMQ、Kafka等可以实现间接的数据交换。
文件方式
如Datebase、File等可以实现间接的数据交换。
共享内存
Java中通过MappedByteBuffer共享内存来实现进程间通讯。
本质是对文件的读写,为避免高并发下的数据错乱,可使用FileLock文件锁对文件加锁操作。
public class WriteShareMemory {
    public static void main(String[] args) {
        try (RandomAccessFile randomAccessFile = new RandomAccessFile("share.mm", "rw")) {
            FileChannel channel = randomAccessFile.getChannel();
            FileLock lock = channel.lock();
            MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 10);
            for (int i = 0; i < 10; i++) {
                buffer.put(i, (byte) i);
                Thread.sleep(2000);
            }
            lock.release();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("写入完成");
    }
}
public class ReadShareMemory {
    public static void main(String[] args) {
        try (RandomAccessFile randomAccessFile = new RandomAccessFile("share.mm", "rw")) {
            FileChannel channel = randomAccessFile.getChannel();
            MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 10);
            FileLock lock;
            while (true) {
                lock = channel.tryLock();
                if (lock == null) {
                    Thread.sleep(2000);
                    System.out.println("locked");
                } else {
                    break;
                }
            }
            for (int i = 0; i < 10; i++) {
                System.out.println(buffer.get(i));
            }
            lock.release();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("读取完成");
    }
}RMI 方式
Remote Method Invoke:远程方法调用。可以实现直接的数据交换。
public interface IRemote extends Remote {
    String testMethod(String a, String b) throws RemoteException;
}
public class RemoteBean extends UnicastRemoteObject implements IRemote {
    private static final long serialVersionUID = 3682470187378911418L;
    protected RemoteBean() throws RemoteException {
    }
    @Override
    public String testMethod(String a, String b) {
        return a + b;
    }
}
public class RmiServer {
    public static void main(String[] args) {
        try {
            IRemote iRemote = new RemoteBean();
            LocateRegistry.createRegistry(1099);
            Registry registry = LocateRegistry.getRegistry();
            registry.bind("test", iRemote);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
public class RmiClient {
    public static void main(String[] args) {
        try {
            Registry registry = LocateRegistry.getRegistry("localhost",1099);
            IRemote iRemote = (IRemote) registry.lookup("test");
            String s = iRemote.testMethod("hello", "world");
            System.out.println(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}如果不使用接口对象IRemote将抛出如下异常,原因是Java动态代理是面向接口的:
java.lang.ClassCastException: class com.sun.proxy.$Proxy0 cannot be cast to class RemoteBean (com.sun.proxy.$Proxy0 and RemoteBean are in unnamed module of loader 'app')
    at RmiClient.main(RmiClient.java:12)
                Views: 4,770 · Posted: 2021-04-16
            
            ————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
 
        Loading...