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();
        }
  • 相关阅读:
    BFS visit tree
    Kth Largest Element in an Array 解答
    Merge k Sorted Lists 解答
    Median of Two Sorted Arrays 解答
    Maximal Square 解答
    Best Time to Buy and Sell Stock III 解答
    Best Time to Buy and Sell Stock II 解答
    Best Time to Buy and Sell Stock 解答
    Triangle 解答
    Unique Binary Search Trees II 解答
  • 原文地址:https://www.cnblogs.com/whoislcj/p/5603277.html
Copyright © 2011-2022 走看看