Java 线程通信:
1共享变量,如volatite等
2wait/notify机制,最好搭配同步锁
3Lock/Condition机制 //condition.await();condition.signalAll();
4管道 //PipedOutputStream out; PipedInputStream in; out.connect(in); //只能建立一次
Java进程通信
1.管道、命名管道
管道是一个固定大小的缓冲区,使用单个固定缓冲区也会带来问题,比如在写管道时可能变满,当这种情况发生时,随后对管道的write()调用将默认地被阻塞,等待某些数据被读取,以便腾出足够的空间供write()调用写。读取进程也可能工作得比写进程快。管道实际上就是一个file结构和一个VFS的索引。也就是说管道是一个虚拟的文件。
注意:从管道读数据是一次性操作,数据一旦被读,它就从管道中被抛弃,释放空间以便写更多的数据。
创建管道要借助C/C++中的mkfifo()函数来创建,这样Java就可以使用该文件,采用类似文件的方式进行通信.
2.信号Signal
信号具有平台相关性,不同平台下能使用的信号种类是有差异的。
在Linux下支持的信号(对比信号列表查看描述)
SEGV, ILL, FPE, BUS, SYS, CPU, FSZ, ABRT, INT, TERM, HUP, USR1, USR2, QUIT, BREAK, TRAP, PIPE
在Windows下支持的信号
SEGV, ILL, FPE, ABRT, INT, TERM, BREAK
SignalHandler signalHandler = new SignalHandler() { @Override public void handle(Signal signal) { System.out.println(signal.getName()); } }; Signal.handle(new Signal("USR2"), signalHandler);//信号注册 Signal.handle(new Signal("HUP"), signalHandler); // kill -1 PID Signal.handle(new Signal("INT"), signalHandler); // kill -2 PID Signal.handle(new Signal("ABRT"), signalHandler); // kill -6 PID Signal.handle(new Signal("ALRM"), signalHandler); // kill -14 PID Signal.handle(new Signal("TERM"), signalHandler); // kill -15 PID Signal.raise(new Signal("USR2")); //发送信号量 Signal.raise(new Signal("INT")); Signal.raise(new Signal("HUP")); Thread.sleep(20000);发送信号前,需要先通过 ps 或 jps 获取java的进程id,然后运行命令行通过kill -s SIGUSR2 pid 发送信号, Java中通过raise发送信号
3.消息队列 :MessageQueue
4.共享内存
因为线程与父进程的其他线程共享该进程所拥有的全部资源。所以创建的线程本来就已经实现共享内存。但要注意的是,在操作共享资源时要注意实现同步机制,确保线程安全。
5.内存映射 如:MappedByteBuffer
6.信号量 如:Semaphore