从操作系统的角度讲,线程间通信比进程间通信要容易的多,因为线程之间可以共享进程的内存空间。因此,他们可以共享位于进程全局数据区和栈和堆上的所有内容。唯一只属于某个线程的就是线程的栈----它可以存放只属于线程的对象。
线程间通信方式:
1. 共享进程的变量。
但要注意不要共享栈上的变量,因为它随时可能被某个线程销毁,而另一个线程就无法访问它了。
所以Java编译器不允许使用栈上的变量来共享。
如下面这个编译器是会报错的:
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
setContentView(R.layout.activity_main);
-
int i=0;
-
Thread a=new Thread(new Runnable(){
-
@Override
-
public void run() {
-
// TODO Auto-generated method stub
-
i++;
-
}
-
-
});
-
}
上面的自动变量i有可能被申请它的线程销毁,因为无法用来进行共享。
2. 消息
也就是Handler,本质上还是对Handler对象的共享,不需要多说。另外Handler也能用在单线程中,用来把事情串行化。
3. TLS(Thread Local Storage)
-
public final class Looper {
-
private static final String TAG = "Looper";
-
-
// sThreadLocal.get() will return null unless you'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;
-
}
上面sThreadLocal就是TLS,就是每个线程都会有一个copy。原理就是每个TLS对每个Thread维护一个动态数组,一个线程对应一个Copy。
线程间通信的管理方式:并发,同步和互斥
1. Java中的Semaphore类,是进行并发控制的,也就是说,它可以限制访问一个资源(或代码块)的线程数目。
当设定的线程数目是1时,并发其实就退化到了互斥。
2. Synchronized,这个是monitor,保证互斥的,一块代码不能同时被两个线程访问。
3. Synchronized+Object的Notify和wait,这三个一起构成了同步。比如下面这段程序,保证了
Thread A和Thread B是交替执行的。
public void onClick_start_thread_a(View v) {
logger.d("onClick_start_thread_a");
Runnable r = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
synchronized (flag) {
System.out.println("Thread A!");
flag.notifyAll();
try
{
flag.wait();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
};
Thread t = new Thread(r);
t.start();
}
public void onClick_start_thread_b(View v) {
logger.d("onClick_start_thread_b");
Runnable r = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
synchronized (flag) {
System.out.println("Thread B!");
flag.notifyAll();
try
{
flag.wait();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
};
Thread t = new Thread(r);
t.start();
}
Lock类也可以取代Notify和Wait
阅读(1318) | 评论(0) | 转发(0) |