多线程-20200422-高级应用

消息队列:生产消费者模型

【1】生产者

【2】消费者

【3】队列

      -生产者生产数据,消费者依次消费

      -生产者当队列满,不再生产

      -消费者当队列空,进入等待

【4】消息中间件:本质同理。

note:this.wait()\this.notifyAll()——获取锁。如果是同一个对象,会直接往下执行。----所以需要多次判断。放弃if , while()

解决问题的思路——技术【池】

【1】SE定制化高 && 实际生产往往更注重效率。

【2】将一些对象放入“池”当中,然后交给池托管这些对象的执行方式。作为使用者,不需要再关心如何管理这些对象

【3】线程池管理分类:

      固定线程池:线程池中,线程



【4】单任务线程,类似join,线程串行执行

      -所有线程用完归池

      -依次执行

【5】可变尺寸的线程池,全部并发

      -

【6】延迟线程池

      -延迟的线程是在其被加入到池当中以后,开始计时。

      -当前线程资源,延迟线程【顺延】

      -延迟线程一样需要竞争资源

【7】自定义线程池——队列

      -至少等于

      -核心线程数量规定当前

      -核心线程数满了后,加入队列;队列是同时可以执行的线程数

      -队列线程数满了后,如果最大线程池的数量没满,则队列外多余的线程同时执行。但:这些线程是不经过线程池管理的线程,他们没有做到对象的重用。

      -如果队列满了,最大线程池数量也满了,则不再接受新的线程执行

      -队列内的线程会被核心线程重复取用

【8】有返回值的线程,实现callable接口

      -任何线程必须join到Callable之后,才会执行。

      -应用场景:当当前线程需要前一个线程的执行结果,才能继续执行时,需要get()结果。

      -如果不需要返回值,则其和普通线程没有任何区别。

自定义线程池

【1】同步方法、同步代码块

【2】使用Lock接口:可以使线程的操作更加精细化

【3】IO流阻塞和运算阻塞【设计线程,设计同步】

      -IO流阻塞:对于数据进行读写或者其他IO操作【偏移量】。——建议尽可能多的划分线程。

      -运算阻塞:在数据的运算过程中,CPU是不会释放资源的。——这种情况下,我们线程的划分最大数量就是CPU的内核数量。

      -大数据当中的流式计算:将运算阻塞转化为IO流阻塞。

【4】读写锁——某一个对象的所有线程,本质锁的是: ReentrantReadWriteLock 对象

      -当多个线程同时访问读锁时,不受影响,可以同时访问。

      -当某个线程获得写锁时,其他线程既不能读,也不能写。【写锁属于独占锁,排他锁】

      -如果先执行读锁,直到所有读锁执行结束,开始写锁。

      -锁只有降级,没有升级;因为写锁时独占锁,而读锁时非独占锁。

      -公平锁

            1:获取锁的模式包括:公平锁和非公平锁。

            2:公平锁:on:true。不存在饥饿状态的线程,所有线程有获得公平的执行几率。【效率会较低】

            3:非公平锁:(默认)on:false。在某种极端情况下,会出现某个或者某几个线程始终处于饥饿状态。

            4:重进入:某个线程,同一时刻,可以持有多个锁。

            5:降级性:写锁的强度要高于读锁。遵循:获取写锁、读锁,释放写锁,此时成为:写锁降级为读锁。

      con:

            1:先获取读锁的情况下,再获取写锁,此时获取写锁失败。【注意:只要发现当前的读锁被占用,则无法获取写锁,不管读锁是否被当前线程持有】           

            2:线程持有写锁情况下,可以继续获取读锁。【注意:获取读锁时,发现写锁被占用,当且仅当写锁没有被当前线程占用的情况下失败】——获取写锁的同时,往往会独占读锁。

            3:由于读锁允许多个线程同时占有,因此读锁不可以升级为写锁。——而写锁往往是独占读锁,可以降级。

           

【5】信号量

     -未达到上限时,可以正常执行;超过上限,则进入阻塞状态。

【6】线程池——阻塞队列  &&  阻塞栈

     -队列是一个单向通道;超出上限以后进入阻塞;没有元素进入阻塞

     -栈是一个双向通道;超出上限以后,返回false;没有元素返回null

【7】条件变量

     -持锁状态下,可以等待和唤醒

     -支持多个对象唤醒

【8】原子量  &&  ThreadLocal

     -即便是原子量,但是整个流程可能亦然不安全,需要线程加锁。

     -保障多个线程对同一个数据的可见性和线程安全性

[9]障碍器

     -有若干子任务需要执行,某个线程需要等到所有的子任务执行完成,才能执行主任务。——障碍器

     -

    

线程中:不允许修改,建议用final;同理传参也是final

构造:传参必须:static final 如果为不可变的话!

final 变量问题

总结一下:不同应用场景

ArrayList &&& linkedList

posted @ 2020-04-26 16:45  小海_macro  阅读(250)  评论(0编辑  收藏  举报