AndroidQueue基础知识整理

引言

在Android应用程序中,我们经常需要使用队列(queue)这种数据结构。队列是一种先进先出(FIFO)的数据结构,它可以非常方便地实现一些常见的任务,比如任务调度、消息传递、事件处理等。Android系统提供了多种队列实现方式,比如ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue等。本文将介绍Android队列的基础知识和使用方法,帮助读者更好地理解Android队列的特性和原理,从而提高应用程序的效率和稳定性。

Android队列的基础知识

一、队列的定义和特性

队列是一种先进先出(FIFO)的数据结构,它有两个基本的操作:入队(enqueue)和出队(dequeue)。队列的特点是只允许在队头进行删除操作,而在队尾进行插入操作。当队列为空时,出队操作会抛出异常或返回空值,而入队操作会将元素插入到队列的队尾。

二、Android队列的实现

Android系统提供了多种队列的实现方式,其中比较常用的有ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue等。这些队列都实现了Java的Queue接口,可以用来存储对象(Object)类型的元素。下面我们将分别介绍这些队列的基本特性和使用方法。

1. ArrayBlockingQueue

ArrayBlockingQueue是一个由数组组成的有界阻塞队列。它的容量在初始化时指定,一旦队列满了,再进行插入操作会被阻塞,直到队列中的元素被取出。同样的,当队列为空时,取出操作也会被阻塞。ArrayBlockingQueue通常用于生产者-消费者模式,其中一个或多个线程进行数据的生产,另外一个或多个线程进行数据的消费。下面是一个ArrayBlockingQueue的示例代码:


import java.util.concurrent.*;

public class ArrayBlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
        new Thread(new Producer(queue)).start();
        new Thread(new Consumer(queue)).start();
    }

    static class Producer implements Runnable {
        private final BlockingQueue<String> queue;

        Producer(BlockingQueue<String> queue) {
            this.queue = queue;
        }

        public void run() {
            try {
                while (true) {
                    String task = String.valueOf(System.currentTimeMillis());
                    queue.put(task);
                    System.out.println("生产:" + task);
                    Thread.sleep(1000);
                }
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

    static class Consumer implements Runnable {
        private final BlockingQueue<String> queue;

        Consumer(BlockingQueue<String> queue) {
            this.queue = queue;
        }

        public void run() {
            try {
                while (true) {
                    String task = queue.take();
                    System.out.println("消费:" + task);
                }
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }
}

2. LinkedBlockingQueue

LinkedBlockingQueue是一个由链表组成的有界阻塞队列。它的容量也可以在初始化时指定,当队列满了或者为空时,操作也会被阻塞。它与ArrayBlockingQueue的不同之处在于LinkedBlockingQueue没有固定大小,可以动态扩展。LinkedBlockingQueue通常用于一组可重复的任务,由多个线程进行消费和生产。下面是一个LinkedBlockingQueue的示例代码:


import java.util.concurrent.*;

public class LinkedBlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> queue = new LinkedBlockingQueue<>();
        new Thread(new Producer(queue)).start();
        new Thread(new Consumer(queue)).start();
    }

    static class Producer implements Runnable {
        private final BlockingQueue<String> queue;

        Producer(BlockingQueue<String> queue) {
            this.queue = queue;
        }

        public void run() {
            try {
                while (true) {
                    String task = String.valueOf(System.currentTimeMillis());
                    queue.put(task);
                    System.out.println("生产:" + task);
                    Thread.sleep(1000);
                }
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

    static class Consumer implements Runnable {
        private final BlockingQueue<String> queue;

        Consumer(BlockingQueue<String> queue) {
            this.queue = queue;
        }

        public void run() {
            try {
                while (true) {
                    String task = queue.take();
                    System.out.println("消费:" + task);
                }
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }
}

3. PriorityBlockingQueue

PriorityBlockingQueue是一个无界阻塞队列,它的元素按照优先级进行排序。元素必须实现Comparable接口,PriorityBlockingQueue使用排序规则来决定元素出队顺序。当队列为空时,取出操作也会被阻塞。PriorityBlockingQueue通常用于一些需要根据优先级进行排序的场景,比如任务调度、事件触发等。下面是一个PriorityBlockingQueue的示例代码:


import java.util.concurrent.*;

public class PriorityBlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<Task> queue = new PriorityBlockingQueue<>();
        new Thread(new Producer(queue)).start();
        new Thread(new Consumer(queue)).start();
    }

    static class Task implements Comparable<Task> {
        private final int priority;
        private final String description;

        Task(int priority, String description) {
            this.priority = priority;
            this.description = description;
        }

        public int getPriority() {
            return priority;
        }

        public String getDescription() {
            return description;
        }

        public int compareTo(Task other) {
            return Integer.compare(priority, other.priority);
        }
    }

    static class Producer implements Runnable {
        private final BlockingQueue<Task> queue;

        Producer(BlockingQueue<Task> queue) {
            this.queue = queue;
        }

        public void run() {
            try {
                while (true) {
                    Task task = new Task(ThreadLocalRandom.current().nextInt(5), String.valueOf(System.currentTimeMillis()));
                    queue.put(task);
                    System.out.println("生产:" + task.getDescription() + " 优先级:" + task.getPriority());
                    Thread.sleep(1000);
                }
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

    static class Consumer implements Runnable {
        private final BlockingQueue<Task> queue;

        Consumer(BlockingQueue<Task> queue) {
            this.queue = queue;
        }

        public void run() {
            try {
                while (true) {
                    Task task = queue.take();
                    System.out.println("消费:" + task.getDescription() + " 优先级:" + task.getPriority());
                }
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }
}

Android队列的使用

一、使用队列进行任务调度

在Android应用程序中,我们经常需要使用队列来进行任务调度。比如,我们需要对多个长时间运行的任务进行调度,可以先将这些任务封装为对象,放入一个队列中,然后通过线程池或手动启动线程进行逐个执行。其中,优先级队列可以非常方便地对任务进行排序和调度,保证高优先级任务先执行。下面是一个使用PriorityBlockingQueue进行任务调度的示例代码:


import java.util.concurrent.*;

public class TaskScheduler {
    private final BlockingQueue<Task> queue = new PriorityBlockingQueue<>();
    private final ExecutorService executor;

    TaskScheduler(int nThreads) {
        executor = Executors.newFixedThreadPool(nThreads);
    }

    public void submit(Task task) {
        queue.put(task);
    }

    public void start() {
        while (true) {
            try {
                Task task = queue.take();
                executor.execute(task);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

    static class Task implements Comparable<Task>, Runnable {
        private final int priority;
        private final String name;

        Task(int priority, String name) {
            this.priority = priority;
            this.name = name;
        }

        public void run() {
            System.out.println("Executing task " + name);
        }

        public int compareTo(Task other) {
            return Integer.compare(priority, other.priority);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        TaskScheduler scheduler = new TaskScheduler(4);
        for (int i = 0; i < 20; i++) {
            scheduler.submit(new Task(ThreadLocalRandom.current().nextInt(10), "Task-" + i));
        }
        scheduler.start();
    }
}

二、使用队列进行消息传递

在Android应用程序中,发送和接收消息是非常常见的行为。可以使用队列来实现消息传递,具体实现方式可以使用两个不同的队列,一个队列用于发送消息,另一个队列用于接收消息。发送端将消息封装为对象放入发送队列中,接收端从接收队列中取出消息对象进行处理。下面是一个使用LinkedBlockingQueue进行消息传递的示例代码:


import java.util.concurrent.*;

public class MessageQueue {
    private final BlockingQueue<Message> sendQueue = new LinkedBlockingQueue<>();
    private final BlockingQueue<Message> receiveQueue = new LinkedBlockingQueue<>();

    public void sendMessage(Message message) {
        sendQueue.offer(message);
    }

    public Message receiveMessage() throws InterruptedException {
        return receiveQueue.take();
    }

    public void start() {
        new Thread(new Sender(sendQueue, receiveQueue)).start();
        new Thread(new Receiver(receiveQueue)).start();
    }

    static class Message {
        private final String content;

        Message(String content) {
            this.content = content;
        }

        public String getContent() {
            return content;
        }
    }

    static class Sender implements Runnable {
        private final BlockingQueue<Message> sendQueue;
        private final BlockingQueue<Message> receiveQueue;

        Sender(BlockingQueue<Message> sendQueue, BlockingQueue<Message> receiveQueue) {
            this.sendQueue = sendQueue;
            this.receiveQueue = receiveQueue;
        }

        public void run() {
            try {
                for (int i = 0; i < 10; i++) {
                    Message message = new Message("Hello, " + i);
                    sendQueue.put(message);
                    System.out.println("发送消息:" + message.getContent());
                    Message response = receiveQueue.take();
                    System.out.println("接收消息:" + response.getContent());
                }
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

    static class Receiver implements Runnable {
        private final BlockingQueue<Message> receiveQueue;

        Receiver(BlockingQueue<Message> receiveQueue) {
            this.receiveQueue = receiveQueue;
        }

        public void run() {
            try {
                while (true) {
                    Message message = receiveQueue.take();
                    System.out.println("处理消息:" + message.getContent());
                    Message response = new Message("Response to " + message.getContent());
                    receiveQueue.put(response);
                }
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MessageQueue messageQueue = new MessageQueue();
        messageQueue.start();
    }
}

三、使用队列进行事件处理

在Android应用程序中,事件处理是非常常见的操作。可以使用队列来实现事件处理,具体实现方式可以使用一个队列来存储事件对象,不同的线程从队列中取出事件进行处理。下面是一个使用ArrayBlockingQueue进行事件处理的示例代码:


import java.util.concurrent.*;

public class EventQueue {
private final BlockingQueue<Event> queue = new ArrayBlockingQueue<>(1000);
private final ExecutorService executor;

EventQueue(int nThreads) {
executor = Executors.newFixedThreadPool(nThreads);
}

public void addEvent(Event event) {
queue.offer(event);
}

public void start

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/285179.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-22 15:43
下一篇 2024-12-22 15:43

相关推荐

  • Python元祖排序:从基础知识到高级应用

    Python元祖是一种不可变序列,通常用于将一组数据绑定在一起。元祖之间经常需要排序,本文将从基础知识到高级应用,为你详细讲解Python元祖排序。 一、排序方法 Python提供…

    编程 2025-04-28
  • 计算机二级基础知识题库

    计算机二级基础知识题库考试为计算机二级考试的必修科目之一,其中包含了计算机的基本知识以及应用能力等内容。本文将从题库概述、考试内容、备考建议以及编程实例等几个方面进行介绍,希望对广…

    编程 2025-04-27
  • 软件测试理论基础知识

    一、测试概述 软件测试是指在已知测试用例的前提下,检查软件是否满足规定的功能和质量要求的过程。 软件测试的目的是要发现并纠正可能存在的缺陷。它涉及软件开发周期的各个阶段,从需求分析…

    编程 2025-04-23
  • MongoDB基础知识

    一、什么是MongoDB MongoDB是一个开源的文档数据库,它采用了类似于JSON的BSON数据格式,可以支持复杂数据结构和动态查询。MongoDB可以减少不必要的关系型数据设…

    编程 2025-02-27
  • PS基础知识详解

    一、图像的格式 1、我们常接触的图像格式有哪些? 在PS中,我们常用的图像格式有:JPEG、PNG、GIF、RAW等。其中JPEG格式适用于图像,PNG格式适用于图像和图标,GIF…

    编程 2025-02-25
  • 内存类型基础知识

    从计算机诞生至今,RAM(随机存取内存)在架构和形态上都经历了重大变革。它们主要分为两种类型:SRAM(静态随机存取内存)和 DRAM(动态随机存取内存)。 DRAM 又可细分为同…

    2025-02-24
  • 图像复原基础知识

    一、噪声的影响 在数字图像中,噪声是无法避免的,而它的出现通常是由于图像采集、传输和处理等过程中引入的。噪声的存在对于图像的清晰度和细节造成了不同程度的影响,因此在图像复原中需要特…

    编程 2025-02-11
  • 魔术封包唤醒基础知识

    一、概念概述 魔术封包唤醒是指一种技术方式,在网络通信中用于唤醒特定设备的一种技术手段,其原理是在局域网内向目标设备发送一种特定的唤醒包,当目标设备接收到该唤醒包后,即可从睡眠状态…

    编程 2025-02-01
  • Linux基础知识

    一、Linux简介 Linux操作系统是一种基于Unix操作系统的自由软件和开源软件,是自由操作系统中最著名的一个。 Linux操作系统包含了一整套完善的工具集,包括系统工具、应用…

    编程 2025-01-27
  • C++运算符:基础知识、用法和示例

    C++运算符是用于计算、比较或逻辑操作的特殊符号。本文将详细介绍C++运算符的基础知识、用法和示例,包括算术运算符、关系运算符、逻辑运算符、位运算符和其他运算符。 一、算术运算符 …

    编程 2025-01-14

发表回复

登录后才能评论