Android多线程实现-Handler详解

Android常用的多线程实现方法

说起多线程编程大家都不陌生,所谓线程就是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。在Android开发中,当我们执行一些耗时操作,比如发起一条网络请求时,我们不知道服务器何时会响应请求,这类操作需要放在新的线程执行,以免阻塞主线程(UI线程)。在Android开发中常用的实现多线程的方式有以下几种:

1.Java原生的实现

作为Android开发常用的语言,Java已经为我们提供了多线程的实现,主要有以下三种方式:
1.继承Thread类,重写run方法;
2.实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target;
3.通过Callable和FutureTask创建线程;

继承Thread类与实现Runnable接口的区别

那么这三种方法也是各有特点,实现Runnable接口方法相比于继承Thread类就有这几个优势:
1)由于Java不支持多继承,因此继承Thread类之后就不可以再继承别的类了,而实现Runnable接口方法可以解决单继承而带来的局限性;
2)增强程序的健壮性,代码能够被多个线程共享,代码与数据是独立的
3)适合多个相同程序代码的线程去处理同一资源的情况
4)线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类
针对2)和3)这两点,我们以卖票系统举个例子,通过继承Thread类方式实现多线程如下:

public class MutliThreadDemo {  
    public static void main(String[] args) {  
        MutliThread m1=new MutliThread("Window 1");   
        MutliThread m2=new MutliThread("Window 2");   
        MutliThread m3=new MutliThread("Window 3");   
        m1.start();  
        m2.start();  
        m3.start();  
    }  
}  
public class MutliThread extends Thread {  
    private int ticket=100;//每个线程都拥有100张票   
  
    public MutliThread (){}  
    public MutliThread (String name){  
        super(name);  
    }  
      
    @Override  
    public void run() {  
        while(ticket>0){   
            System.out.println(ticket--+" is saled by "+Thread.currentThread().getName());   
        }   
    }  
}  

从结果可以看到,每个线程分别对应100张电影票,之间并无任何关系,这就说明每个线程之间是平等的,系统会分别为其分配内存资源。而如果我们要实现资源共享,也就是说这些线程卖同一份票池,使用这种方法就无法实现了,而使用Runnable接口方式就可以解决这个问题:

public class MutliThreadDemo {  
    public static void main(String[] args) {  
        MutliThread m=new MutliThread();   
        Thread t1=new Thread(m);   
        Thread t2=new Thread(m);   
        Thread t3=new Thread(m);   
        t1.start();   
        t2.start();   
        t3.start();   
    }  
} 
public class MutliThread implements Runnable{   
    private int ticket=100;//每个线程都拥有100张票   
    public void run(){   
        while(ticket>0){   
            System.out.println(ticket--+" is saled by "+Thread.currentThread());   
        }   
    }   
}  

如上所示,程序在内存中仅创建了一份资源,而新建的三个线程都是访问同一资源的。
在第一种方法中中,要想开多个线程,就要先new多个自定义类MutliThread对象,每一个自定义类MyThread的对象的成员变量都相同,这样需要在栈中开辟很多内存;
在第二种方法中中,要想开多个线程,只需要new一个自定义类MutliThread的对象,再new多个Thread类的对象即可,这样就大大节约了内存。
因此,我们说Runnable接口方式相比于继承Thread类方式,适合多个相同程序的代码去处理同一个资源的情况,能够把线程同程序的代码和数据有效分离(即耦合性降低),较好的体现了Java面向对象的设计思想。

实现Runnable接口与实现Callable接口的区别

实现Runnable接口和实现Callable接口的区别主要有以下几点:
1)Runnable是自从java1.1就有了,而Callable是1.5之后才加上去的
2)实现Callable接口的任务线程能返回执行结果(需要调用FutureTask.get()方法实现,但会阻塞主线程直到获取返回结果),而实现Runnable接口的任务线程不能返回结果
3)Callable接口的call()方法允许抛出异常,而Runnable接口的run()方法的异常只能在内部消化,不能继续上抛
4)加入线程池运行,Runnable使用ExecutorService的execute方法,Callable使用submit方法

我们看到相比于Runnable接口方法,Callable接口可以返回执行结果。因此如果你希望任务在完成的能返回一个值,那么可以通过Callable接口实现。Callable接口使用泛型去定义它的返回类型,它的参数类型表示的是从方法call()(不是run())中返回的值,下面简单说一下用用法。
首先定义一个类实现java.util.concurrent包下的Callable接口,然后重写里面的call方法(相当于其他方法的run()函数),创建ExecutorService线程池,将自定义类的对象放入线程池里面,即可获取线程的返回结果,最后,关闭线程池,不再接收新的线程,未执行完的线程不会被关闭。简单的示例如下:

public static void main(String[] args) {
        
    //创建线程池对象
    ExecutorService pool &#
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值