从操作系统的角度讲,线程间通信比进程间通信要容易的多,因为线程之间可以共享进程的内存空间。因此,他们可以共享位于进程全局数据区和栈和堆上的所有内容。
唯一只属于某个线程的就是线程的栈-------它可以存放只属于线程的对象。
下面逐一解读线程间通信方式:
1. 共享进程的变量
这是最基本的通信方式,但要注意不要共享线程栈上的变量,因为它随时可能被某个线程销毁,而另一个线程就无法访问它了。
所以Java编译器不允许使用栈上的变量来共享。
例子1:
如下面这个编译器是会报错的,
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int i=0;
Thread a=newThread(new Runnable(){
@Override
public voidrun() {
// TODOAuto-generated method stub
i++;
}
});
}
上面的自动变量i可以看做是进程的变量,但它有可能被申请它的线程销毁,因为无法用来进行共享。
例子2:
正面的例子比如android中的handler,它是需要在进程空间共享的。
2. TLS(Thread Local Storage)
线程本地存储,本质上是存储一系列线程号和Looper对象的key-value键值对。
比如Android的Looper
public finalclass Looper {
privatestatic final String TAG = "Looper";
// sThreadLocal.get() will return null unlessyou've called prepare().
static final ThreadLocal<Looper>sThreadLocal = new ThreadLocal<Looper>();
private static Looper sMainLooper; //guarded by Looper.class
final MessageQueue mQueue;
final Thread mThread;
private Printer mLogging;
}
Looper有一个静态的
static final ThreadLocal<Looper> sThreadLocal = newThreadLocal<Looper>();
ThreadLocal本质上是一系列线程号和Looper对象的key-value键值对,因为sThreadLocal是静态的,所以它为所有的线程所共享。
而sThreadLocal.get()就是获取当前线程对应的Looper。
例子:
起一个Worker线程来做事情
private static class Worker implementsRunnable {
……
publicvoid run() {
synchronized(mLock) {