Java\Android 多线程实现方式及并发与同步

概念

原文来自:https://blog.csdn.net/csdn_aiyang/article/details/65442540

了解什么是进程?什么是线程?

进程:是系统的执行单位,每一个Application都是一个进程,APP启动时系统默认有一个主线程即为UI线程,但是UI线程不能做耗时操作,这里就要把耗时的操作交给子线程执行

线程:Thread 是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。

线程的几种状态:

1、wait() -等待状态 ,并且释放所有持有对象的lock锁,直到notify()/notifyAll()被唤醒后放到锁定池(lock blocked pool ),释放同步锁使线程回到可运行状态(Runnable)。

2、sleep()。使一个线程处于睡眠状态,是一个静态方法,调用此方法要捕捉Interrupted异常,醒来后进入runnable状态,等待JVM调度。

3.notify();换新一个等待状态的线程,这个将要唤醒的线程是由JVM的分配的优先级线程来调度并唤醒;

4.notifyAll()使所有等待状态的线程唤醒,让他们竞争

5.join()。使一个线程中断,IO完成会回到Runnable状态,等待JVM的调度

6.Synchronized();同步锁。使Running状态的线程加同步锁使其进入(lock blocked pool ),同步锁被释放进入可运行状态(Runnable)。

7.yield(),线程礼让 。当线程在runnable状态时是处于被调度的线程,此时的调度顺序是不一定的。Thread类中的yield方法可以让一个running状态的线程转入runnable。

基础性概念

1.并行 : 当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。

2. 并行当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。

     区别:并发和并行是即相似又有区别的两个概念,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。在多道程序环境下,并发性是指在一段时间内宏观上有多个程序在同时运行,但在单处理机系统中,每一时刻却仅能有一道程序执行,故微观上这些程序只能是分时地交替执行。倘若在计算机系统中有多个处理机,则这些可以并发执行的程序便可被分配到多个处理机上,实现并行执行,即利用每个处理机来处理一个可并发执行的程序,这样,多个程序便可以同时执行

3、线程安全。指在并发的情况之下,该代码经过多线程使用,线程的调度顺序不影响任何结果。线程不安全就意味着线程的调度顺序会影响最终结果,比如某段代码不加事务去并发访问。

4、线程同步。指的是通过人为的控制和调度,保证共享资源的多线程访问成为线程安全,来保证结果的准确。如某段代码加入@synchronized关键字。线程安全的优先级高于性能优化。

5.原子性。一个操作或者一系列操作,要么全部执行要么全部不执行。数据库中的“事物”就是个典型的院子操作。

6、可见性。当一个线程修改了共享属性的值,其它线程能立刻看到共享属性值的更改。比如JMM分为主存和工作内存,共享属性的修改过程是在主存中读取并复制到工作内存中,在工作内存中修改完成之后,再刷新主存中的值。若线程A在工作内存中修改完成但还来得及刷新主存中的值,这时线程B访问该属性的值仍是旧值。这样可见性就没法保证。

7、有序性。程序运行时代码逻辑的顺序在实际执行中不一定有序,为了提高性能,编译器和处理器都会对代码进行重新排序。前提是,重新排序的结果要和单线程执行程序顺序一致。

常见的多线程的实现方式

1、继承Thread类,重写run函数方法:


2、实现Runnable接口,重写run函数方法

3、实现Callable接口,重写call函数方法:

Runnable 和Callable接口比较:

相同点:都可以被其他线程执行任务

不同点:

a.重写的方法不同 

 b Runnable重写的方法不可以抛出异常, 并无返回值  

c.运行Callable任务可拿到一个Future对象,Future表示异步计算的结果。通过Future对象可了解任务执行情况,可取消任务的执行。

4.Handler + Thread 

HandlerThread的好处是代码看起来没前面的版本那么乱,相对简洁一点。还有一个好处就是通过handlerThread.quit()或者quitSafely()使线程结束自己的生命周期。

5  AsyncTask

HandlerThread只开一条线程,任务都被阻塞在一个队列中,那么就会使阻塞的任务延迟了

想多个耗时任务并发的执行,那你更应该选择AsyncTask。

耗时任务执行的四个方法:

onPreExecute();

doInBackground();

onProgressUpdate() ;

onPostExecute()


6.IntentService

最后是IntentService,相信很多人也不陌生,它是Service的子类,用法跟Service也差不多,就是实现的方法名字不一样,耗时逻辑应放在onHandleIntent(Intent intent)的方法体里,它同样有着退出启动它的Activity后不会被系统杀死的特点,而且当任务执行完后会自动停止,无须手动去终止它。例如在APP里我们要实现一个下载功能,当退出页面后下载不会被中断,那么这时候IntentService就是一个不错的选择了。

你可能感兴趣的:(Java\Android 多线程实现方式及并发与同步)