Android和Java之并发多线程(详细归纳和讲述)

12 篇文章 0 订阅

如果关注了本人的博客,前面有一篇这样的博客,讲述是:Java单机模式下重要的两个知识点(数据检索和并发线程)

https://blog.csdn.net/zh_android/article/details/90721884  这里我们来详细谈谈并发线程。

 

Android和Java之并发多线程

有些工程师将并发和多线程当成一个概念,在软件开发中这样概念还不少,如:依赖注入和控制反转,高内聚和低耦合。原因是它们谈论的是一个东西,现在的计算机大多都是多核的,来提高性能。谈并发就离不多线程,用多线程就离不开并发。

 

用多线程,我们就不得不弄明白什么是线程,其实我不想说什么是线程,因为刚学软件开发时候,一开始就会讲这个。但是它又很抽象,好像若见若无,看不明白。在这里举个例子,说说自己的看法:

把计算机看成一个大型的工业机器,线程就是一个创建运行起来的发动机,只是它是在CPU里面调用发动,通过程序指令不断的运行,只要是程序,一启动,它就跑起来了一个或多个线程。

 

多线程是什么?多线程就是多个指令部分跑起来运行,指令部分可以一样,也可以不一样。它们一起来抢占CPU的资源。

 

呈上面讲的:多线程一起抢占CPU资源,就可以引入一个很重要的概念:并发锁!

有并发,就会有锁!为什么?打个比方,CPU资源就是保存了一条数据a=100,多个线程去访问,增删查改操作,没有锁锁住就会有数据不一致和混乱。加了锁,不论是增删查改那个操作,一个操作结束以后,释放锁才进行下一个操作,就不会数据不一致的情况。

 

  • 线程的创建:包括创建线程和创建线程池
  1. 线程的创建:

  方式一:Java1.0引入Thread和Runable接口

  方式二:Java5.0引入Callable,Future,FutureTask

          通过方式一创建线程无法获取子线程的运行结果,所以引入了方式二,Future接口可以理解为一个任务,通过Future.get()方法获取运行的结果。

  方式三:Java7.0引入fork/join框架

         fork/join框架在java.util.concurent包下。fork/join框架包含:Recursive,Task,Forkjoinpool

  方式四:Java8.0引入了Completable

        通过Completable可以定义回调函数,子线程执行完以后,会触发回调函数

 

 

  1. 线程池的创建:

java.uitl.concurrent.ThreadPoolExecutor类是线程池中最核心的一个类,因此如果要透彻地了解Java中的线程池,必须先了解这个类。下面我们来看一下ThreadPoolExecutor类的具体实现源码。

  在ThreadPoolExecutor类中提供了四个构造方法:

public class ThreadPoolExecutor extends AbstractExecutorService {

    .....

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,

            BlockingQueue<Runnable> workQueue);

 

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,

            BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);

 

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,

            BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);

 

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,

        BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);

 

Java通过Executors提供四种线程池,分别为:
线程池一:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
线程池二:newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
线程池三:newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
线程池四:newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

 

  • 线程的辅助类

线程的辅助类:主要是封装用来做多个线程交互调用的过程。

辅助类一:CountDownLatch

   利用它可以实现类似于计数器的功能,如:有一个任务A,它要等到其他几个任务都完成以后才执行,此时可以利用CountDownLatch来实现这个功能。

辅助类二:CyclicBarrier

   字面的意思是回环栅栏,通过它可以实现让一组线程等待到某个状态以后在全部同时执行,这叫做回环。

辅助类三:Semaphore

   字面意思是信号量,可以控制访问线程的个数,通过acquire()获取一个许可,如果没有就等待,用release()释放一个许可。

辅助类四:Phaser

Phaser表示“阶段器”,用来解决控制多个线程分阶段共同完成任务的情景问题。其作用相比CountDownLatch和CyclicBarrier更加灵活。

  • 并发集合

   并发集合指的是具有线程安全的集合。

集合一:HashTable

集合二:ConcurrentHashMap  

集合三:CopyOnWriteArrayList 

集合四:CopyOnWriteArraySet 

集合五:ArrayBlockingQueue

 

  • 并发线程的核心原理

以上图:

1.volatile变量是用于java内存数据共享时定义的变量,本质就是多线程数据共享时定义的变量,方便保证原子性,进行读写操作。

2.CAS 是CopyAndSwap,中文解释是复制即交换。本质是在进行多线程操作时,复制一个副本来操作,结束值赋值给原变量,保证并发情况下数据的一致性。

3.AQS是AbstractQueuedSynchronizer(AQS),中文解释是抽象的队列式的同步器,定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch。

(本博客后期还会完善和修改,谢谢关注)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Frank浩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值