zoukankan      html  css  js  c++  java
  • 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();
        }
  • 相关阅读:
    spring3创建RESTFul Web Service
    安装Maven
    如何使用 JSP JSTL 显示/制作树(tree) 菜单
    Eclipse EE导入maven工程
    安装PL/SQL Developer,链接本地64位Oracle
    Maven项目消除奇怪的红叉
    如何禁用Eclipse的Validating
    帮助文档总览
    MySQL下载安装、配置与使用(win7x64)
    C#知识点总结:Monitor和Lock以及区别
  • 原文地址:https://www.cnblogs.com/whoislcj/p/5603277.html
Copyright © 2011-2022 走看看