您当前的位置:首页 > 互联网教程

java 进程间通讯的有几种方法

发布时间:2025-05-20 14:29:20    发布人:远客网络

java 进程间通讯的有几种方法

一、java 进程间通讯的有几种方法

1、JAVA进程间通信的方法主要有以下几种:

2、(1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。

3、(2)命名管道(named pipe):命名管道克服了管道没有名字的限制,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。

4、(3)信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身。

5、(4)消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。

6、(5)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。

7、(6)内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。

8、(7)信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。

9、(8)套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。

二、Android进程间和线程间通信方式

    进程:是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。

  线程:是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一些在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。

  (1)、一个程序至少有一个进程,一个进程至少有一个线程;

  (2)、线程的划分尺度小于进程,使得多线程程序的并发性高;

  (3)、进程在执行过程中拥有独立的内存单元,而多个线程共享内存,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉。

  由于Activity,Service,Receiver都是可以通过Intent来携带Bundle传输数据的,所以我们可以在一个进程中通过Intent将携带数据的Bundle发送到另一个进程的组件。

  缺点:无法传输Bundle不支持的数据类型。

  ContentProvider是Android四大组件之一,以表格的方式来储存数据,提供给外界,即Content Provider可以跨进程访问其他应用程序中的数据。用法是继承ContentProvider,实现onCreate,query,update,insert,delete和getType方法,onCreate是负责创建时做一些初始化的工作,增删查改的方法就是对数据的查询和修改,getType是返回一个String,表示Uri请求的类型。注册完后就可以使用ContentResolver去请求指定的Uri。

  两个进程可以到同一个文件去交换数据,我们不仅可以保存文本文件,还可以将对象持久化到文件,从另一个文件恢复。要注意的是,当并发读/写时可能会出现并发的问题。

  Broadcast可以向android系统中所有应用程序发送广播,而需要跨进程通讯的应用程序可以监听这些广播。

  Service和Content Provider类似,也可以访问其他应用程序中的数据,Content Provider返回的是Cursor对象,而Service返回的是Java对象,这种可以跨进程通讯的服务叫AIDL服务。

     AIDL通过定义服务端暴露的接口,以提供给客户端来调用,AIDL使服务器可以并行处理,而Messenger封装了AIDL之后只能串行运行,所以Messenger一般用作消息传递。

  Messenger是基于AIDL实现的,服务端(被动方)提供一个Service来处理客户端(主动方)连接,维护一个Handler来创建Messenger,在onBind时返回Messenger的binder。

  双方用Messenger来发送数据,用Handler来处理数据。Messenger处理数据依靠Handler,所以是串行的,也就是说,Handler接到多个message时,就要排队依次处理。

  Socket方法是通过网络来进行数据交换,注意的是要在子线程请求,不然会堵塞主线程。客户端和服务端建立连接之后即可不断传输数据,比较适合实时的数据传输

  一般说线程间通信主要是指主线程(也叫UI线程)和子线程之间的通信,主要有以下两种方式:

  AsyncTask,异步任务,也就是说在UI线程运行的时候,可以在后台的执行一些异步的操作;AsyncTask可以很容易且正确地使用UI线程,AsyncTask允许进行后台操作,并在不显示使用工作线程或Handler机制的情况下,将结果反馈给UI线程。但是AsyncTask只能用于短时间的操作(最多几秒就应该结束的操作),如果需要长时间运行在后台,就不适合使用AsyncTask了,只能去使用Java提供的其他API来实现。

  Handler,继承自Object类,用来发送和处理Message对象或Runnable对象;Handler在创建时会与当前所在的线程的Looper对象相关联(如果当前线程的Looper为空或不存在,则会抛出异常,此时需要在线程中主动调用Looper.prepare()来创建一个Looper对象)。使用Handler的主要作用就是在后面的过程中发送和处理Message对象和让其他的线程完成某一个动作(如在工作线程中通过Handler对象发送一个Message对象,让UI线程进行UI的更新,然后UI线程就会在MessageQueue中得到这个Message对象(取出Message对象是由其相关联的Looper对象完成的),并作出相应的响应)。

  面试的过程中,有些面试官可能会问Android子线程之间的通信方式,由于绝大部分程序员主要关注的是Android主线程和子线程之间的通信,所以这个问题很容易让人懵逼。

  主线程和子线程之间的通信可以通过主线程中的handler把子线程中的message发给主线程中的looper,或者,主线程中的handler通过post向looper中发送一个runnable。但looper默认存在于main线程中,子线程中没有Looper,该怎么办呢?其实原理很简单,把looper绑定到子线程中,并且创建一个handler。在另一个线程中通过这个handler发送消息,就可以实现子线程之间的通信了。

  子线程创建handler的两种方式:

  方式一:给子线程创建Looper对象:

       public void run(){ 

         Looper.prepare(); //给这个Thread创建Looper对象,一个Thead只有一个Looper对象

         Handler handler= new Handler(){ 

          @Override 

           public void handleMessage(Message msg){ 

             Toast.makeText(getApplicationContext(),"handleMessage", Toast.LENGTH_LONG).show(); 

          } 

        }; 

         handler.sendEmptyMessage(1); 

         Looper.loop();//不断遍历MessageQueue中是否有消息

      }; 

    }).start();

    方式二:获取主线程的looper,或者说是UI线程的looper:

       public void run(){ 

         Handler handler= new Handler(Looper.getMainLooper()){//区别在这!!! 

          @Override 

           public void handleMessage(Message msg){ 

             Toast.makeText(getApplicationContext(),"handleMessage", Toast.LENGTH_LONG).show(); 

          } 

        }; 

         handler.sendEmptyMessage(1); 

      }; 

    }).start();

三、服务进程与一般程序进程通信要注意什么问题

1、你不能指望WM_COPYDATA在两台计算机直线传数据。

2、1)传输层面的通信,这里主要是指TCP/UDP,你可以在服务程序上开一个Socket端口进行侦听,然后客户端程序开Socket端口去连接服务器程序。这么做的话,你什么数据都可以传,但是不好的地方就是需要自己定义传输控制协议。

3、2)架构在现有应用层协议上的通信。典型的如在HTTP协议上做的通信。数据传输协议由HTTP本身控制,自己只需要关心自己的数据。这里面最最典型的情况就是WebService。服务器端用Java或者.NET将服务功能编写为WebService,客户端通过HTTP协议向服务器以POST方式发送数据,并得到服务器端的计算结果。使用这种方式都是用标准的通信端口,可以避开网络上的防火墙带来的烦恼。不像直接用Socket传输需要自定义端口,在网络上开例外,并且还得处理代理的情况。当然你还可以在HTTP协议上传输其他的协议,比如MSNP。

4、3)基于对象层面的通信。这里主要是指COM+.NET Remoting等等,用户完全不必关心数据的传输和格式。只需关心业务的处理。客户端程序并不直接调用远端服务器程序,而是调用本地的一个服务器程序代理对象,再由代理对象向服务器程序进行数据交互通信。微软提供的此类通信协议主要是RPC和WebService。

5、一般来说,如果你需要通信的数据种类单一,要求处理速度快,可以考虑直接用Socket。如果通信协议复杂,就需要使用WebService或者COM+通过RPC协议进行通信。