【Android】多线程知识汇总

汇总知识

《Java并发编程之美》学习笔记 - 简书

并发编程- java.util.concurrent用户指南 - 简书

Java高并发必学--concurrent包-腾讯云开发者社区-腾讯云

并发编程基础 - 安全性、活跃性、性能问题_竞态条件和活跃性问题 性能问题-CSDN博客

线程

进程和线程概览

Java 多线程编程 | 菜鸟教程

并发系列(1)之 Thread 详解 - 三枣 - 博客园

Thread类讲解_thread类详解-CSDN博客

多线程系列(二) -Thread类使用详解

线程状态

  • 新建(New):新建后未启动的线程;
  • 运行(Runnable):包括运行中(Running)和就绪(Ready)两种状态;也就是正在运行,或者等待 CPU 分配执行时间;
  • 等待(Waiting):无限期的等待其他线程显示唤醒;
  • 超时等待(Timed_Waiting):一定时间内没有被其他线程唤醒,则由系统自动唤醒;
  • 阻塞(Blocked):等待获取排它锁;
  • 终止(Terminated):运行终止;

线程间的通讯

其实所有的多线程问题,其本质都是线程之间的通讯问题,也有的说是通讯和同步两个问题(线程间操作的顺序);但我觉得同步仍然是线程之间通过某种方式进行通讯,确定各自执行的相对顺序;所以仍然可以算作是一种通讯问题;这里线程之间的通讯问题可以分成两种:

  • 共享变量,类似锁对象、volatile、中断等操作都可以算是共享变量通讯;
  • 消息传递,类似 wait\notify、管道等则可以算是通过消息直接传递通讯;

中断线程

线程停止的三种方式超详细-CSDN博客

中断线程一般会设置标志位,而设置标志位分两种方式:

  1. 直接自己定义一个标志位,作为线程是否结束的标记

  2. 使用标准库里自带的一个标志位;

    使用 Thread.currentThread().isInterrupted() 作为标志位

    public class Demo3 {
       public static void main(String[] args) {
           Thread t = new Thread(()->{
              while(!Thread.currentThread().isInterrupted()){
                  System.out.println("hello Thread");
              }
               System.out.println("t 执行完");
           });
    
           t.start();
    
           try {
               Thread.sleep(300);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
    
           t.interrupt();
           System.out.println("设置让 t 线程结束");
       }
    }
    

注意:interrupt 方法的行为,有两种情况

① 当 t 线程在运行状态时,会设置标志位(Thread.currentThread().isInterrupted())为 true;

② 当 t 线程在阻塞状态时(sleep),就不会设置标志位,而是触发一个 InterruptedException,这个异常会把 sleep 提前唤醒。

java线程取消与关闭的多种方法_future 关闭线程-CSDN博客

关闭线程的正确方法:“优雅”的中断 - 简书

线程中的异常捕获

Thread对象通过setUncaughtExceptionHandler方法来设置UncaughtExceptionHandler;

Future

重学多线程之一:Future

多线程基础之设计模式Future模式_线程 future-CSDN博客

Future 模式: 买蛋糕时,与其一直等待结果, 不如先拿一张 "提货单", 获取提货单并不耗费时间, 这里的 "提货单" 我们就称为 Future 角色

多线程基础之设计模式Thread-Per-Message模式_thread per message-CSDN博客

Future与FutureTask接口实现示例详解java脚本之家

Java之Future(cancel,iSDone)_future.isdone-CSDN博客

CompletableFuture

异步编程利器:CompletableFuture详解

Java8新特性:CompletableFuture 方法介绍_java supplyasync whencomplete-CSDN博客

HandlerThread

Android多线程:HandlerThread的原理及使用 - 简书

守护线程

Java基础(二十)——守护线程(setDaemon)、合并线程(join)、读写分离集合(CopyOnWriteArrayList)、生产者消费者模式-CSDN博客

线程池

JAVA阻塞队列和线程池原理_java线程池为什么使用阻塞队列作为任务队列-CSDN博客

Android开发-通过ExecutorService构建一个APP使用的全局线程池_android 定义全局线程池类-CSDN博客

线程池的任务执行顺序:核心线程(corePoolSize),线程队列workQueue,非核心线程(maximumPoolSize),都满了则执行线程提交拒绝策略(handler)。

Java线程池七个参数详解_线程池七大核心参数-CSDN博客

终止线程池

关闭线程的正确方法:“优雅”的中断 - 简书

线程池的shutdown()与shutdownNow()方法的区别-CSDN博客

Java线程池,isShutDown、isTerminated的作用与区别 - 疯子110 - 博客园

定时执行者服务 ScheduledExecutorService

ScheduledExecutorService详解-CSDN博客

scheduleAtFixedRate (Runnable, long initialDelay, long period, TimeUnit timeunit)

如果一个任务占用了比计划的时间间隔更长的时候,下一次执行将在当前执行结束执行才开始。计划任务在同一时间不会有多个线程同时执行。

scheduleWithFixedDelay (Runnable, long initialDelay, long period, TimeUnit timeunit)

除了 period 有不同的解释之外这个方法和 scheduleAtFixedRate() 非常像。

scheduleAtFixedRate() 方法中,period 被解释为前一个执行的开始和下一个执行的开始之间的间隔时间。而在本方法中,period 则被解释为前一个执行的结束和下一个执行的结束之间的间隔。因此这个延迟是执行结束之间的间隔,而不是执行开始之间的间隔。

AsyncTask

Android学习笔记:多个AsyncTask实例的并发问题 - 51kata - 博客园

ANDROID的AsyncTask为何弃用 asynctask缺点

线程池的封装

线程池 - 简书

原子性Atomic包

线程安全性详解(原子性、可见性、有序性)-原子性可见性有序性

并发编程-04线程安全性之原子性Atomic包的4种类型详解_atomiclong线程安全-CSDN博客

线程安全之AtomicBoolean_线程安全的boolean-CSDN博客

原子操作类AtomicInteger详解-CSDN博客

多线程(七)原子操作、阻塞队列_atomicboolean 默认值-CSDN博客

set()方法注意

.set()方法:设置指定值,无锁,多线程使用会出问题,一般用于初始化数值

    AtomicInteger
    /**
     * Sets to the given value.
     *
     * @param newValue the new value
     */
    public final void set(int newValue) {
        value = newValue;
    }

lazySet()方法与set()方法区别

lazySet()方法没有缓存刷新。

换句话说,我们的变化最终只对其他线程可见。这意味着从不同的线程对更新的 AtomicReference 调用 get()可能会给我们带来旧的值。

高并发的问题

AtomicLong,CAS的过程中,当A线程在C(compare)和S(swap)之间有其他线程插入S,则,A线程的S始终执行不了,一直在循环,待A线程的A和S之间没有其他线程插入S时,才能S成功。但实际按执行顺序A线程不是在最后,导致最终会S错误的值。

如果对结果和执行顺序有严格要求,可以用锁。

Happens-Before原则(先行发生原则)

Happens-Before原则(先行发生原则) - 简书

Condition类,等待

java中Condition类的详细介绍(详解) - 郭慕荣 - 博客园

LongAdder(累加器,java8新加入)

LongAdder详解 - 简书

Java LongAdder类介绍、代码示例、底层实现原理及与分段锁的区别-CSDN博客

原理

适用于高并发对单一变量增减后,进行求和取值。

当多个线程同时进行加法操作时,每个线程都会被分配到一个独立的"cell",从而减少了竞争条件。

当需要获取最终的加法结果时,LongAdder会将"base"和所有"cell"中的值进行求和,得到最终的结果。

对比AtomicLong

在高度并发竞争情形下,AtomicLong每次进行add都需要flush和refresh(这一块涉及到java内存模型中的工作内存和主内存的,所有变量操作只能在工作内存中进行,然后写回主内存,其它线程再次读取新值),每次add()都需要同步,在高并发时会有比较多冲突,比较耗时导致效率低;

而LongAdder中每个线程会维护自己的一个计数器,在最后执行LongAdder.sum()方法时候才需要同步,把所有计数器全部加起来,不需要flush和refresh操作; AtomicLong耗时间;LongAdder耗内存;

AtomicLong,高并发结果可能会出错,详见上方<原子性Atomic包>之<高并发的问题>。

Java中的锁

Java中的锁详解篇_java 锁-CSDN博客

Java中的锁(synchronized、Lock、ReadWriteLock)及常用线程安全类原理(CopyOnWriteArrayList、ConcurrentHashMap)_java四种锁机制-CSDN博客

乐观锁的机制CAS:Compare-And-Swap比较并交换

线程学习(25)-乐观锁方式CAS简介_cas方式-CSDN博客

CAS:线程始终在高速运行,没有停歇;

synchronized:会让线程在没有获得锁的时候,发生上下文切换,进入阻塞;

CAS效率高的原因:线程就好像高速跑道上的赛车,高速运行时,速度超快,一旦发生上下文切换,就好比赛车要减速、熄火,等被唤醒又得重新打火、启动、加速... 恢复到高速运行,代价比较大;

AtomicInteger类主要利用CAS + volatile和native方法来保证原子操作,从而避免synchronized的高开销,提升执行效率。

CAS实际应用的场景应该是,线程数量较少,多核CPU的情况,这种情况下,使用CAS可以提升效率。

ABA问题

ABA问题-CSDN博客

synchronized

全网最硬核的 synchronized 面试题深度解析_synchronized面试题-CSDN博客

synchronized - 简书

Synchronized相比ReentrantLock,在使用偏向锁时甚至都不需要自旋。因此在锁细粒度很小的情况下,Synchronized不太会升级为重量级锁,此时性能上会比ReentrantLock更加优秀。

进阶

ForkJoinPool

ForkJoinPool 分支/合并框架_forkjoinpool.managedblocker-CSDN博客

线程池ForkJoinPool简介 - Java老K - 博客园

ForkJoinPool的使用及基本原理_51CTO博客_forkjoinpool使用场景

Handler机制

闲聊Android中的Handler机制

全面详解Android实现多线程的几种方式(史上最全,最详细)_android多线程实现方式-CSDN博客

子线程中使用Handler

Android如何在子线程中使用Handler_handler运行在子线程如何写-CSDN博客

Handler的使用_子线程中使用handler的场景-CSDN博客

其他问题

单例Bean一定不安全吗?

面试官:单例Bean一定不安全吗?实际工作中如何处理此问题?-51CTO.COM

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容