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: 3,553 · Posted: 2021-04-16
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
Loading...