前篇总结:上一篇说明了线程通信原理,这一篇我们模拟Android的主线程子线程通信同时解决上篇提到的多个线程访问全局一个公有的消息队列引起的加锁同步问题,不安全问题。
第二节 主线程子线程通信
在每个子线程中都加个消息队列,首先实现主线程和子线程通信:
public class TestThreadMsg2 {
static class Thread1 extends Thread{
//线程的阻塞消息队列
LinkedTransferQueue mQueue = new LinkedTransferQueue();
@Override
public void run() {
super.run();
for (;;) {
String message = null;
try {
message = (String) mQueue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程:"+Thread.currentThread().getId()+" 收到:"+message);
if (message.equals("子线程去干活吧!")){
System.out.println("子线程:"+Thread.currentThread().getId()+" do work!");
System.out.println("");
System.out.println("");
}
}
}
}
public static void main(String[] args){
Thread1 t1 = new Thread1();
t1.start();
for (;;) {
try {
String message="子线程去干活吧!";
System.out.println("主线程:"+Thread.currentThread().getId()+" 发送:"+message);
t1.mQueue.put(message);
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
代码也很简单同样不必多说,主线程和子线程通信实现了那反过来,子线程和主线程通信也很简单了。下面我们模拟Android中常用子线程和主线程通信:
public class TestThreadMsg3 {
public static TestThreadMsg3 MainThread;//主线程
static LinkedTransferQueue messageQueue;//主线程的阻塞消息队列
public TestThreadMsg3() {
MainThread = this;
}
public static void main(String[] args){
messageQueue = new LinkedTransferQueue();
Thread1 t1 = new Thread1();
t1.start();
for (;;) {
String message = null;
try {
message = (String) messageQueue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程:"+Thread.currentThread().getId()+" 收到:"+message);
if (message.equals("主线程去更新UI吧")){
System.out.println("主线程:"+Thread.currentThread().getId()+" do work!");
System.out.println("");
System.out.println("");
}
}
}
static class Thread1 extends Thread{
@Override
public void run() {
super.run();
for (;;) {
try {
String message="主线程去更新UI吧";
System.out.println("子线程:"+Thread.currentThread().getId()+" 发送:"+message);
MainThread.messageQueue.put(message);//放到主线程的消息队列里
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
我们虽然模拟了Android的子线程和主线程通信,但是思考一下如果你是Android的工程师你会怎么设计才能让广大程序猿方便使用线程间通信?
我觉得最最先想到的就是重写一个Thread类默认就加上消息队列和消息循环(就是那个读取消息队列的死循环),但是这样貌似有点太强硬了也不灵活。比如多数情况下都是写个子线程执行耗时任务这个子线程不需要接收消息,只会把消息发给主线程。如何设计才更合理?
google大神们采用Looper解决,下一篇将实现仿写一个Looper来管理消息队列和消息循环: