做单页网站怎么选产品,宝安高端网站建设公司,广州快速排名,域名价格是怎么收费的同步和异步的差异
同步#xff1a;在发生某件事后什么也不做#xff0c;直到该事件完成后#xff0c;再继续进行
异步#xff1a;在某件事发生后#xff0c;可以在等待他完成的时候去处理其他事件#xff0c;等到该事件发生完成后#xff0c;再回过头来处理它。
异步…同步和异步的差异
同步在发生某件事后什么也不做直到该事件完成后再继续进行
异步在某件事发生后可以在等待他完成的时候去处理其他事件等到该事件发生完成后再回过头来处理它。
异步操作的核心思想就是将耗时操作放到子线程中执行避免阻塞主线程从而保持界面的流畅性。
异步实现方法
Thread Looper handler
Android 提供了 Handler 机制来进行线程之间的通信我们可以使用 Android 最基础的异步方式Thread Looper handler 来进行异步任务
Handler mHandler newHandler(){Overridepublicvoid handleMessage(Message msg){if(msg.what 1){textView.setText(Task Done!!);}}
};
mRunnable new Runnable() {Overridepublicvoid run() {SystemClock.sleep(1000); // 耗时处理mHandler.sendEmptyMessage(1); }
};
private void startTask(){new Thread(mRunnable).start();
}优点
操作简单无学习成本。
缺点
代码规范性较差不易维护。每次操作都会开启一个匿名线程系统开销较大。
AsyncTask
AsyncTask是较为轻量级的异步类封装了 FutureTask 的线程池、ArrayDeque 和 Handler 进行调度。AsyncTask 主要用于后台与界面持续交互。
当我们定义一个类来继承 AsyncTask 这个类的时候我们需要为其指定3个泛型参数 AsyncTask Params, Progress, Result Params: 这个泛型指定的是我们传递给异步任务执行时的参数的类型。Progress: 这个泛型指定的是我们的异步任务在执行的时候将执行的进度返回给UI线程的参数的类型。Result: 这个泛型指定的异步任务执行完后返回给UI线程的结果的类型。我们在定义一个类继承 AsyncTask 类的时候必须要指定好这三个泛型的类型如果都不指定的话则都将其写成 void。 使用 AsyncTask 的注意事项
AsyncTask 的实例必须在 UI Thread 中创建。只能在 UI 线程中调用 AsyncTask 的 execute 方法。AsyncTask 被重写的四个方法是系统自动调用的,不应手动调用。每个 AsyncTask 只能被执行一次多次执行会引发异常。AsyncTask 的四个方法只有 doInBackground 方法是运行在其他线程中,其他三个方法都运行在 UI 线程中也就说其他三个方法都可以进行 UI 的更新操作。AsyncTask 默认是串行执行如果需要并行执行使用接口 executeOnExecutor 方法。
优点 结构清晰使用简单适合后台任务的交互。 异步线程的优先级已经被默认设置成了THREAD_PRIORITY_BACKGROUND不会与 UI 线程抢占资源。
缺点 结构略复杂代码较多。 每个 AsyncTask 只能被执行一次多次调用会发生异常。 AsyncTask 在整个 Android 系统中维护一个线程池有可能被其他进程的任务抢占而降低效率。
线程池
利用 Executors 的静态方法 newCachedThreadPool()、newFixedThreadPool()、newSingleThreadExecutor() 及重载形式实例化 ExecutorService 接口即得到线程池对象。
动态线程池 newCachedThreadPool()根据需求创建新线程的需求多时创建的就多需求少时JVM 自己会慢慢的释放掉多余的线程。固定数量的线程池 newFixedThreadPool()内部有个任务阻塞队列假设线程池里有2个线程提交了4个任务那么后两个任务就放在任务阻塞队列了即使前2个任务 sleep 或者堵塞了也不会执行后两个任务除非前2个任务有执行完的。单线程 newSingleThreadExecutor()单线程的线程池这个线程池可以在线程死后或发生异常时重新启动一个线程来替代原来的线程继续执行下去。
例子 下面代码中新建了一个固定数量为4的线程池
Database(entities {AccountDataItem.class, AccountData.class},version 6,exportSchema false)
public abstract class AppRoomDataBase extends RoomDatabase {private static volatile AppRoomDataBase INSTANCE;public abstract AccountDao accountDao();public abstract AccountListDao accountListDao();public static final ExecutorService databaseWriteExecutor Executors.newFixedThreadPool(4);// 单例模式public static AppRoomDataBase getDataBase(Context context){if (INSTANCE null) {synchronized (AppRoomDataBase.class) {if (INSTANCE null) {INSTANCE Room.databaseBuilder(context.getApplicationContext(),AppRoomDataBase.class,记账数据库).fallbackToDestructiveMigration().build();}}}return INSTANCE;}
} public void deleteAllAccountItem() {appRoomDataBase.databaseWriteExecutor.execute(() - accountDao.deleteAll());}
优点
线程的创建和销毁由线程池来维护实现了线程的复用从而减少了线程创建和销毁的开销。适合执行大量异步任务提高性能。灵活性高可以自由控制线程数量。扩展性好可以根据实际需要进行扩展。
缺点
代码略显复杂。线程池本身对系统资源有一定消耗。当线程数过多时线程之间的切换成本会有很大开销从而使性能严重下降。每个线程都会耗费至少 1040KB 内存线程池的线程数量需要控制在一定范围内。线程的优先级具有继承性如果在 UI 线程中创建线程池线程的默认优先级会和 UI 线程相同从而对 UI 线程使用资源进行抢占。
LiveData