为了账号安全,请及时绑定邮箱和手机立即绑定

Android线程管理之Thread使用总结

标签:
Android

前言

     最近在一直准备总结一下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();
    }

复制代码

 

干我们这行,啥时候懈怠,就意味着长进的停止,长进的停止就意味着被淘汰,只能往前冲,直到凤凰涅槃的一天!

原文链接:http://www.apkbus.com/blog-508687-62891.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消