概览
首先啥是线程,啥是进程。
首先线程和进程是两个截然不同的概念,线程是CPU调度的最小单元,同时线程是一种有限的系统资源。而进程一般是指一个执行单元。
虽然定义上毫不相干,但进程和线程之间是有包含关系的:一个Android程序至少要有一个进程,而一个进程最少要有一个线程实现功能。同时如果深入到虚拟机去理解,,安卓为每一个进程都分配了一个虚拟机,该虚拟机的栈堆等不共享,静态变量、对象等无法共享,当一个程序以多进程的模式运行,可以说线程同步机制完全失效。所以理解多进程也能加深对多线程的理解。
多线程要考虑的是数据共用问题,那么多进程之间则需要注意进程之间的通信机制。
首先是线程通信
public class ProducerConsumerTest {
public static void main(String[] args) {
CubbyHole c = new CubbyHole();
Producer p1 = new Producer(c, 1);
Consumer c1 = new Consumer(c, 1);
//对象实例化
p1.start();
c1.start();
//开启线程
}
}
class CubbyHole {
//仓库类
private int contents;
private boolean available = false;
public synchronized int get() {
while (available == false) {
try {
wait();
}
catch (InterruptedException e) {
}
}
available = false;
notifyAll();
return contents;
}
public synchronized void put(int value) {
while (available == true) {
try {
wait();
}
catch (InterruptedException e) {
}
}
contents = value;
available = true;
notifyAll();
}
}
class Consumer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Consumer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
value = cubbyhole.get();
System.out.println("消费者 #" + this.number+ " got: " + value);
}
}
}
class Producer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Producer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
for (int i = 0; i < 10; i++) {
cubbyhole.put(i);
System.out.println("生产者 #" + this.number + " put: " + i);
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) { }
}
}
}
这是一个生产者消费者的例子,通过这个例子可以看到生产者消费者线程之间存在着沉睡和唤醒的关系的,这只是一个简单的例子
Android中的跨进程通信
使用Intent
1.Activity、Service、Receiver都支持在Intent中传输Bundle数据,而Bundle实现了Parcelable接口,可以在不同的进程间进行传输
2.在一个进程中启动另一个进程的Activity,Service和Receiver在Bundle中附加要传输的数据通过Intent发送出去
使用文件共享
1.windows上文件有锁,Linux没有
2.在一个进程中进行序列化一个对象到文件系统,在另一个进程中反序列化恢复这个对象
3.SharedPreferences是个特例,系统对它的读写有缓存策略
使用Messenger
Massenger是一种轻量级的IPC方案,它的底层是AIDL,可以在不同的进程中传递Message,它一次只处理一个请求。在服务端不需要考虑线程同步的问题
AIDL
AIDL可以解决并发和跨境成调用方法的问题,Messenger本质上也是AIDL,只不过系统做了封装方便上层使用。
使用ContentProvider
底层实现还是Binder和AIDL,ContentProvider的底层数据可以是SQLite数据,可以是文件,也可以是内存中的数据。