Android中多线程处理

来源:互联网 发布:淘宝卖家电话在哪里 编辑:程序博客网 时间:2024/06/05 02:48

     无论如何在Android中都无法避免多线程和并发的操作,并发有可能是app用户请求服务器对服务器来说的并发也有可能是app本身存在多线程并发,今天我们就先从Java基础知识了来学习多线程和并发的操作。


      关于线程Thread和Runnable的基本使用就不多说,我们先介绍下控制线程同步的几种方法:

     (1)使用synchronized修饰方法、代码块,方法中的变量。

     (2)使用volatile修饰成员变量。

     (3)使用阻塞队列---BlockingQueue实现同步。

      本部分就介绍BlockingQueue的使用。

      首先BoockingQueue是一个接口,它有四个实现子类,分别是:

       (1)ArrayBlockingQueue:规定大小的BlockingQueue,在创建时,构造函数必须制定int类型的大小,它遵循FIFO的原则。

       (2)LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定.其所含的对象是以FIFO(先入先出)顺序排序的。

       (3)PriorityBlockingQueue:类似于LinkedBlockQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数的Comparator决定的顺序.

       (4)SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取交替完成的.

       下面先给出一个ArrayBlockingQueue的使用实例:

       

/** 创建10个Runnable的Blocking队列 */private static BlockingQueue<Runnable> mArrayBlockQueue = new ArrayBlockingQueue<Runnable>(10);    /**     * 一个测试用到的线程     *      * @author Administrator     *     */    private static class BlockThread implements Runnable {        String name;        public BlockThread(String name) {            this.name = name;        }        public void run() {            System.out.println("--->" + name);        }    }    /**     * 初始化mArrayBlockQueue队列     */    private static void initArrayBlockQueue() {        for (int i = 0; i < 10; i++) {            BlockThread block = new BlockThread("张三" + i);            boolean boo = mArrayBlockQueue.add(block);            System.out.println(boo);        }    }//最后在main()方法中使用队列,遍历取出所有的Runnable    public static void main(String[] args) {        initArrayBlockQueue();        System.out.println("线程大小:" + mArrayBlockQueue.size());        // 遍历取出队列中的Runnable        for (int i = 0; i < mArrayBlockQueue.size(); i++) {            try {                mArrayBlockQueue.take().run();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }
      上面是一个ArrayBlockingQueue队列的简单使用,我们应该注意的是在创建ArrayBlockingQueue对象的时候指定了其大小为10,在初始化(存入Runnable对象的时候)时调用了其add()方法,并且在取出时调用了take()方法,其实BlockingQueue提供了多种方法存入和取出数据。下面详细介绍下这些方法:

      (1)add(object):添加一个对象到BlockingQueue,如果添加成功就返回true,如果添加不成功(比如添加的内容超过其容量)则会直接抛出异常导致程序崩溃。

      (2)offer(object):添加一个对象到BlockingQueue,如果添加成功就返回false,如果添加失败就返回false,无论如何也不会抛出异常,即使添加失败程序也运行正常。

      (3)take():取走BlockingQueue里排在首位的对象,BlockingQueue为空,阻断进入等待状态直到Blocking有新的对象被加入为止

      (4)peek():从BlockingQueue取出一个值,但是不删除,因此每次获取都是第一个元素。

      (5)poll():从BlockingQueue取出一个值,同时删除该元素。


         实际上,查看源码我们会发现,add()方法实际上是调用了offer()方法,而offer()和put()都最终都调用了insert()方法,然后将对象保存在一个Object数组中。

       BlockingQueue是一个接口,他有四个实现类,下面分别介绍:   

      1) ArrayBlockingQueue:规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小.其所含的对象是以FIFO(先入      先出)顺序排序的.

      2) LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定.其所含的对象是以FIFO(先入先出)顺序排序的

      3) PriorityBlockingQueue:类似于LinkedBlockQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数的Comparator决定的顺序.

      4) SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取交替完成的.

      说到这里,那么BlockingQueue在什么地方用呢?通常我们用在多线程同步控制上,如果有很多线程需要其同步执行,那么使用BlockingQueue是再适合不过的了。

       此外,使用阻塞队列也是实现生产--消费者机制的很好的一个案例,测试代码如下:

      

private static BlockingQueue<String> as = new ArrayBlockingQueue<String>(20);public static void main(String[] args) {// 先消费,发现没有就会阻塞,知道生产者生产了对象customer();// 生产producter();}/** * 生产者 */private static void producter() {new Thread(new Runnable() {@Overridepublic void run() {int i = 0;while (true) {i++;try {// 每隔1秒生产一个对象Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}as.add("哈哈-->" + i);if (i >= 10) {System.out.println("队列大小为:" + as.size());break;}}}}).start();}/** * 消费者 */private static void customer() {new Thread(new Runnable() {@Overridepublic void run() {try {while (true) {System.out.println(as.take());}} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}).start();}


      



0 0
原创粉丝点击