Android开发经验谈Android开发Android技术知识

Android 多线程之几个基本问题

2018-07-11  本文已影响47人  AntDream

Android中的进程和线程

  • Android中的一个应用程序一般就对应着一个进程,多进程的情况可以参考Android 多进程通信之几个基本问题
  • Android中更常见的是多线程的情况,一个应用程序中一般都有包括UI线程等多个线程。Android中规定网络访问必须在子线程中进行,而操作更新UI则只能在UI线程。
  • 常见的网络请求库,如OkHttp、Volly等都为我们封装好了线程池,所以我们在进行网络请求时一般不是很能直观地感受到创建线程以及切换线程的过程。
  • 线程是一种很宝贵的资源,要避免频繁创建销毁线程,一般推荐用线程池来管理线程。

线程的状态

线程可能存在6种不同的状态:新创建(New)、可运行(Runnable)、阻塞状态(Blocked)、等待状态(Waiting)、限期等待(Timed Waiting)、终止状态(Terminated)

创建线程

创建线程一般有如下几种方式:继承Thread类;实现Runnable接口;实现Callable接口

public class TestThread extends Thread {
    @Override
    public void run() {
        System.out.println("Hello World");
    }

    public static void main(String[] args) {
        Thread mThread = new TestThread();
        mThread.start();
    }
}
public class TestRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Hello World");
    }

    public static void main(String[] args) {
        TestRunnable mTestRunnable = new TestRunnable();
        Thread mThread = new Thread(mTestRunnable);
        mThread.start();
    }
}
public class TestCallable {

    public static class MyTestCallable implements Callable<String> {

        @Override
        public String call() throws Exception {
            //call方法可以提供返回值,而Runnable不行
            return "Hello World";
        }
    }

    public static void main(String[] args) {
        MyTestCallable myTestCallable = new MyTestCallable();
        //手动创建线程池
        ExecutorService executorService = new ThreadPoolExecutor(1,1,0L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(10));
        //运行callable可以拿到一个Future对象
        Future future = executorService.submit(myTestCallable);
        try {
            //等待线程结束,future.get()方法会使当前线程阻塞
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }
}

线程中断

同步的几种方法

同步的方式一般有如下3种:volatile关键字、synchronized关键字、重入锁ReentrantLock

volatile关键字
public class VolatileTest {
    private volatile int lower,upper;

    public int getLower() {
        return lower;
    }

    public void setLower(int value) {
        if (value > upper) {
            throw new IllegalArgumentException();
        }
        this.lower = value;
    }

    public int getUpper() {
        return upper;
    }

    public void setUpper(int value) {
        if (value < lower) {
            throw new IllegalArgumentException();
        }
        this.upper = value;
    }
}
synchronized关键字和重入锁ReentrantLock
public class ReentrantLockTest {
    private Lock mLock = new ReentrantLock();
    //true,表示实现公平锁
    <!--private Lock mLock = new ReentrantLock(true);-->
    private Condition condition;

    private void thread1() throws InterruptedException{
        mLock.lock();
        try {
            condition = mLock.newCondition();
            condition.await();
            System.out.println("thread1:Hello World");
        }finally {
            mLock.unlock();
        }
    }

    private void thread2() throws InterruptedException{
        mLock.lock();
        try {
            System.out.println("thread2:Hello World");
            condition.signalAll();
        }finally {
            mLock.unlock();
        }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读