美文网首页
Android中的线程通讯

Android中的线程通讯

作者: 卜卜Bruce | 来源:发表于2018-04-05 23:20 被阅读0次

线程

android中的线程是执行Runnable接口的Thread

代码如下

new Thread(new Runnable() {
            @Override
            public void run() {
                //设置线程优先级,减少与UI线程的竞争
                android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
            }
        }).start();

代码执行在Runnable.run()里面。
通过android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND)可以设置线程的优先级别,减少线程与UI线程的竞争。
[除此以外android还提供了更好的选择HandlerThread, AsyncTask, 和IntentService.]

线程池

ThreadPoolExecutor能管理程序,开发者只需要把线程加入线程队列即可。
创建线程池的时候需要舒适化一些参数,见下面代码,摘抄自阿里巴巴的ANDROID开发手册

        //获取可用cpu核数量
        int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
        //运行完后的存活时间
        int KEEP_ALIVE_TIME = 1;
        //运行完后的存活时间的单位
        TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
        //存放线程的队列
        BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>();
        ExecutorService executorService = new ThreadPoolExecutor(NUMBER_OF_CORES,
                NUMBER_OF_CORES*2, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, taskQueue,
                new BackgroundThreadFactory(), new DefaultRejectedExecutionHandler());
        //执行任务
        executorService.execute(new Runnable() {
            @Override
            public void run() {

            }
        });
    //创建后台线程
    private class BackgroundThreadFactory implements ThreadFactory {
        @Override
        public Thread newThread(@NonNull final Runnable r) {
            Runnable wrapperRunnable = new Runnable() {
                @Override
                public void run() {
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    r.run();
                }
            };
            return new Thread(wrapperRunnable);
        }
    }
    /*拒绝策略,当队列满后的处理方式,系统提供了
     *AbortPolicy
     *DiscardPolicy
     *DiscardOldestPolicy
     *CallerRunsPolicy
     */
    private class DefaultRejectedExecutionHandler implements RejectedExecutionHandler {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {

        }
    }

线程通信

线程间通讯分为两种,一种是和主线通讯,一种是后台线程之间通讯。
当与主线程通信的时候,是不可以阻塞主线程的,所以一般使用handler来通信。
先创建一个在UI线程的Handler

    Handler handler = new UiHandler();

    private static class UiHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    //更新UI等操作
                    break;
                default:
                    break;
            }
        }
 

然后执行完耗时操作之后发消息给主线程去执行UI操作

        executorService.execute(new Runnable() {
            @Override
            public void run() {
                // 耗时操作
                handler.obtainMessage(1).sendToTarget();
            }
        });

后台线程之间的通信主要涉及到同步与互斥。
如果在不同线程中操作同一数据,可能造成数据读写状态不同步,那么我们就需要在每一次的读写中锁住这个值。
如下两个线程。

      class RunableA implements Runnable{
        @Override
        public void run() {
            synchronized (MainActivity.class){
                Log.d("hah","A start");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Log.d("hah","A end");
            }
        }
    }
    class RunableB implements Runnable{
        @Override
        public void run() {
            synchronized (MainActivity.class){
                Log.d("hah","b start");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Log.d("hah","b END");
            }
        }
    }
        executorService.execute(new RunableA());
        executorService.execute(new RunableB());

打印如下:
14:56:53.083 3382-3395/activity.activitytest D/bruce: A start
14:56:55.083 3382-3395/activity.activitytest D/bruce: A end
14:56:55.153 3382-3396/activity.activitytest D/bruce: b start
14:56:57.153 3382-3396/activity.activitytest D/bruce: b END

可见B 是等 A 释放之后才运行的。

再来看看wait和notify的应用。

    class RunableA implements Runnable{
        @Override
        public void run() {
            synchronized (MainActivity.class) {
                Log.d("bruce", "A wait");
                try {
                    MainActivity.class.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                Log.d("bruce", "A start");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Log.d("bruce", "A end");
            }
        }
    }
    class RunableB implements Runnable{
        @Override
        public void run() {
            synchronized (MainActivity.class) {
                Log.d("bruce", "b start");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Log.d("bruce", "b END");
                MainActivity.class.notify();
            }
        }
    }

线程A 开始的时候先wait,然后在线程B结束的时候notify
打印如下:
15:17:34.423 4365-4378/? D/bruce: A wait
15:17:34.423 4365-4379/? D/bruce: b start
15:17:36.423 4365-4379/activity.activitytest D/bruce: b END
15:17:36.423 4365-4378/activity.activitytest D/bruce: A start
15:17:38.433 4365-4378/activity.activitytest D/bruce: A end

会发现先执行A然后等待,接着开始制定B 等B notify之后又开始执行A;

以上就是线程的简单应用。

相关文章

  • Android中的线程通讯

    线程 android中的线程是执行Runnable接口的Thread 。 代码如下 代码执行在Runnable.r...

  • Android Handler基本原理

    Android 中Handler 常用来做线程间通讯,另一种说法是用来切换线程,笔者认为称之通讯更为妥当,为什么这...

  • Android中的多线程

    1. Java多线程基础 Java多线程,线程同步,线程通讯 2. Android常用线程 HandlerThre...

  • Android线程通讯

    进程(Process)通常表现为一个正在运行的应用程序实体,在默认情况下,每个正在运行的应用程序有且只有1个进程线...

  • Android Handler源码阅读(技术记录/回忆)

    Handler是Android中最常用线程通讯方式之一、也是非UI线程与线程通讯的主要方式。 你可能有个疑问基础a...

  • Handler基础理论知识

    简介 在Android开发中,我们经常需要在工作线程中进行夸线程通讯实现UI操作,这时就会使用到Handler。 ...

  • Handler Looper MessageQueue 源码分析

    概述 Handler是Android常见的线程间通讯工具,特别是Android UI的主线程的消息循环,下文对Ha...

  • Handler、Lopper、MessageQueue流程梳理

    目的:handle的出现主要是为了解决线程间通讯。 举个例子,android是不允许在主线程中访问网络,因为这样会...

  • Handler机制

    1.为何引入Handler机制Handler是线程间通讯的机制,Android中,网络访问、文件处理等耗时操作必须...

  • Android跨线程通讯

    太长了,不想看? 在Android开发中,我们需要正确的在不同的线程中开展工作: 总是在UI线程中响应用户操作以及...

网友评论

      本文标题:Android中的线程通讯

      本文链接:https://www.haomeiwen.com/subject/frbdhftx.html