Android线程管理之Thread使用(一)

前言

最近在一直准备总结一下Android上的线程管理,今天先来总结一下Thread使用。

实现Thread两种方式

1.)继承Thread类
 /**
     * 继承Thread方式
     */
    private class SyncThread extends Thread {

        SyncThread(String name) {
            super(name);
        }

        @Override
        public void run() {
           //执行耗时操作
        }
    }

示例:

 SyncThread syncThread1 = new SyncThread("线程一");
 SyncThread syncThread2 = new SyncThread("线程二");
 SyncThread syncThread3 = new SyncThread("线程三");

 syncThread1.start();
 syncThread2.start();
 syncThread3.start();
2.)实现Runnable接口
   /**
     * 实现Runnable方式
     */
    private class SyncRunnable implements Runnable {
        @Override
        public void run() {
            //执行耗时操作
        }
    }

示例:

SyncRunnable syncRunnable = new SyncRunnable();
Thread syncThread1 = new Thread(syncRunnable, "线程一");
Thread syncThread2 = new Thread(syncRunnable, "线程二");
Thread syncThread3 = new Thread(syncRunnable, "线程三");

syncThread1.start();
syncThread2.start();
syncThread3.start();

Thread主要函数

run()//包含线程运行时所执行的代码

start()//用于启动线程

sleep()/sleep(long millis)//线程休眠,交出CPU,让CPU去执行其他的任务,然后线程进入阻塞状态,sleep方法不会释放锁

yield()//使当前线程交出CPU,让CPU去执行其他的任务,但不会是线程进入阻塞状态,而是重置为就绪状态,yield方法不会释放锁

join()/join(long millis)/join(long millis,int nanoseconds)//等待线程终止,直白的说 就是发起该子线程的线程 只有等待该子线程运行结束才能继续往下运行

wait()//交出cpu,让CPU去执行其他的任务,让线程进入阻塞状态,同时也会释放锁

interrupt()//中断线程,自stop函数过时之后,我们通过interrupt方法和isInterrupted()方法来停止正在运行的线程,注意只能中断已经处于阻塞的线程

getId()//获取当前线程的ID

getName()/setName()//获取和设置线程的名字

getPriority()/setPriority()//获取和这是线程的优先级 一般property用1-10的整数表示,默认优先级是5,优先级最高是10,优先级高的线程被执行的机率高

setDaemon()/isDaemo()//设置和判断是否是守护线程

currentThread()//静态函数获取当前线程

Thread线程主要状态

(1) New  一旦被实例化之后就处于new状态

(2) Runnable 调用了start函数之后就处于Runnable状态

(3) Running 线程被cpu执行 调用run函数之后 就处于Running状态

(4)   Blocked 调用join()、sleep()、wait()使线程处于Blocked状态

(5)   Dead    线程的run()方法运行完毕或被中断或被异常退出,线程将会到达Dead状态

如何停止一个线程

通过上面的函数列表,我可以知道通过interrupt方法和isInterrupted()方法来停止正在运行的线程,首先必须先让线程处于阻塞状态

    /**
     * 销毁线程方法
     */
    private void destroyThread() {
        try {
            if (null != thread && Thread.State.RUNNABLE == thread .getState()) {
                try {
                    Thread.sleep(500);
                    thread .interrupt();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            thread = null;
        }
    }

Thread线程同步问题

线程的同步是为了防止多个线程访问一个数据对象时,造成数据不一致的问题。

1.)举例说明:比如多线程操作一个全局变量
    private int count = 100;
    private boolean isRunning = false;
    private void test1() {
        isRunning=true;
        SyncThread syncThread1 = new SyncThread("线程一");
        SyncThread syncThread2 = new SyncThread("线程二");
        SyncThread syncThread3 = new SyncThread("线程三");

        syncThread1.start();
        syncThread2.start();
        syncThread3.start();

    }

    /**
     * 继承Thread方式
     */
    private class SyncThread extends Thread {

        SyncThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            while (isRunning) {
                count();
            }
        }
    }

未加同步的count函数

    private void count() {
        if (count > 0) {
            Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
        } else {
            isRunning = false;
        }
    }

执行结果:仔细观察会发现有数据错乱的现象

添加同步的count函数

    private void count() {
        synchronized (this) {
            if (count > 0) {
                Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
            } else {
                isRunning = false;
            }
        }
    }

执行结果

2.)线程同步的几种方式

同样还是以上面的为例

(1)同步函数

   private synchronized void count() {
        if (count > 0) {
            Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
        } else {
            isRunning = false;
        }
    }

(2)同步代码块

  private void count() {
        synchronized (this) {
            if (count > 0) {
                Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
            } else {
                isRunning = false;
            }
        }
    }

(3)使用特殊域变量(volatile)实现线程同步

 private volatile int count = 1000;

  a.volatile关键字为域变量的访问提供了一种免锁机制,
  b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新,
  c.因此每次使用该域就要重新计算,而不是使用寄存器中的值
  d.volatile不会提供任何原子操作,它也不能用来修饰final类型的变量

(4)使用重入锁实现线程同步

ReentrantLock() : 创建一个ReentrantLock实例

lock() : 获得锁

unlock() : 释放锁

    private void count() {
        lock.lock();
        if (count > 0) {
            Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
        } else {
            isRunning = false;
        }
        lock.unlock();
    }
时间: 2024-08-28 12:11:07

Android线程管理之Thread使用(一)的相关文章

Android线程管理(三)——Thread类的内部原理、休眠及唤醒

线程通信.ActivityThread及Thread类是理解Android线程管理的关键. 线程,作为CPU调度资源的基本单位,在Android等针对嵌入式设备的操作系统中,有着非常重要和基础的作用.本小节主要从以下三个方面进行分析: <Android线程管理(一)——线程通信> < Android线程管理(二)——ActivityThread > < Android线程管理(三)——Thread类的内部原理.休眠及唤醒 > 三.Thread类的内部原理.休眠及唤醒 3

Android线程管理(二)&mdash;&mdash;ActivityThread

线程通信.ActivityThread及Thread类是理解Android线程管理的关键. 线程,作为CPU调度资源的基本单位,在Android等针对嵌入式设备的操作系统中,有着非常重要和基础的作用.本小节主要从以下三个方面进行分析: <Android线程管理(一)--线程通信> <Android线程管理(二)--ActivityThread>  <Android线程管理(三)--Thread类的内部原理.休眠及唤醒> 二.ActivityThread的主要工作及实现机

Android线程管理&mdash;&mdash;线程通信

线程通信.ActivityThread及Thread类是理解Android线程管理的关键. 线程,作为CPU调度资源的基本单位,在Android等针对嵌入式设备的操作系统中,有着非常重要和基础的作用.本小节主要从以下三个方面进行分析: <Android线程管理--线程通信> <Android线程管理--ActivityThread> <Android线程管理--Thread> 一.Handler.MessageQueue.Message及Looper四者的关系 在开发A

Android线程管理(二)——ActivityThread

线程通信.ActivityThread及Thread类是理解Android线程管理的关键. 线程,作为CPU调度资源的基本单位,在Android等针对嵌入式设备的操作系统中,有着非常重要和基础的作用.本小节主要从以下三个方面进行分析: <Android线程管理(一)——线程通信> <Android线程管理(二)——ActivityThread> <Android线程管理(三)——Thread类的内部原理.休眠及唤醒> 二.ActivityThread的主要工作及实现机制

Android线程管理之AsyncTask异步任务(四)

前言: 前面几篇文章主要学习了线程以及线程池的创建与使用,今天来学习一下AsyncTask异步任务,学习下AsyncTask到底解决了什么问题?然而它有什么弊端?正所谓知己知彼百战百胜嘛! 产生背景: 我们都知道Android应用程序是单线程模型,在子线程无法直接操作UI主线程,必须通过Handler机制,想了解这方面的知识可以参考这篇文章:Android消息传递之Handler消息机制(一),所以基于这种考虑所以我们一般情况会采用Thread+Handler来处理比较耗时的操作,但是我们都知道

Android线程管理之ThreadLocal理解及应用场景(五)

前言: 最近在学习总结Android的动画效果,当学到Android属性动画的时候大致看了下源代码,里面的AnimationHandler存取使用了ThreadLocal,激起了我很大的好奇心以及兴趣!查阅了一下资料发现Android最重要的Handler消息机制里面的Looper存储也是采用ThreadLocal,开源框架EventBus存储当前线程下的发送事件队列状态也是采用ThreadLocal,那么为何要使用ThreadLocal呢?ThreadLocal是什么呢?它能解决什么样的问题呢

Android线程管理之ThreadPoolExecutor自定义线程池(三)

前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己来自定义一个线程池,今天来学习一下ThreadPoolExecutor,然后结合使用场景定义一个按照线程优先级来执行的任务的线程池. ThreadPoolExecutor ThreadPoolExecutor线程池用于管理线程任务队列.若干个线程. 1.)ThreadPoolExecutor构造函数

Android线程管理之ExecutorService线程池(二)

前言: 上篇学习了线程Thread的使用,今天来学习一下线程池ExecutorService. 为什么要引入线程池? 1.)new Thread()的缺点 每次new Thread()耗费性能 调用new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制创建,之间相互竞争,会导致过多占用系统资源导致系统瘫痪. 不利于扩展,比如如定时执行.定期执行.线程中断 2.)采用线程池的优点 重用存在的线程,减少对象创建.消亡的开销,性能佳 可有效控制最大并发线程数,提高系统资源的使用率,同

Android线程管理(一)——线程通信

一.Handler.MessageQueue.Message及Looper四者的关系 在开发Android多线程应用时,Handler.MessageQueue.Message及Looper是老生常谈的话题.但想彻底理清它们之间的关系,却需要深入的研究下它们各自的实现才行.首先,给出一张它们之间的关系图: Looper依赖于MessageQueue和Thread,因为每个Thread只对应一个Looper,每个Looper只对应一个MessageQueue. MessageQueue依赖于Mes