多线程笔记

1.指令重排

在多线程中,while (!ready),在执行的时候可能会变成

if(!ready) {

while(true) {

}

}

导致其他线程更改了ready的值也没用。

变量加上volatile,volatile使用了内存栅栏,内存栅栏中大多数操作不能被重排序。

指令重排也可能导致两条代码执行顺序颠倒。

Thread.yield() ///线程放弃CPU时间片,重新竞争,可能别人拿到,也可能还是自己拿到。

2.volatile

volatile能保证可见性和禁止指令重排。DCL(双重检查加锁)的变量记得用volatile修饰,如果初始化执行顺序为1-3-2,则可能有问题。

初始化过程:

1-分配内存。2-初始化对象。3-地址赋值给变量。

3.发布对象

对象的发布需要在初始化完成后,否则可能存在不一致状态。

4.对象的同步

保存在volatile修饰的域中。

保存在final修饰的域中。

保存在由锁保护的域中。读取和修改都用同一个锁同步。

5.ExecutorService

shutdown() 拒绝新的任务,并处理完正在执行和队列中的任务。

shutdownNow() 拒绝新的任务,结束正在执行的任务。 返回未执行的任务

awaitTermination()

接受新任务,把等待的任务和执行中的都处理完再关闭,可以传入超时时间。返回是否关闭成功。

isShudDown() 执行了shutdown()或shutdownNow()后返回true。

isTerminated() shutdown()或shutdownNow()执行完毕后返回true。

6.关闭钩子--JVM关闭时运行

Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {

    @Override

    public void run() {

        System.out.println("运行关闭钩子");

    }

}));

7.ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize,                                int maximumPoolSize,                                long keepAliveTime,                                TimeUnit unit,                                BlockingQueue<Runnable> workQueue,                                ThreadFactory threadFactory,                                RejectedExecutionHandler handler)

基准线程数量,最大线程数量,线程空闲回收时间,时间单位,堵塞队列,线程工程,拒绝策略。

invokeAny(List<Callable> list) //获取最快执行完的结果,其他的中断执行。

invokeAll(List<Callable> list) //等待所有都执行完。获取结果集

继承可以使用:

beforeExecute(Thread t, Runnable t) //任务运行前执行

afterExecute(Thread t, Runnable t) //任务运行前执行

terminated() //线程池销毁的时候调用

execute() //没有返回值,运行时异常会打印到控制台

submit() //返回future,运行时异常不会打印到控制台,线程死了get返回null                

8.上下文切换

jvm和操作系统中消耗CPU时钟周期越多,留给应用程序的就越少,但上下文切换并不只是包含jvm和操作系统的开销。当一个新线程切进来,它所需数据可能不在当前cpu缓存,过多的上下文切换会导致性能下降。

对大多数处理器,上下文切换开销相当于5000-10000个时钟周期,也就是几微秒。

9.放弃CPU使用权(可能导致上下文切换)

sleep //自己进入堵塞状态,让出CPU

yield //自己进入就绪状态,优先让其他线程获得CPU使用权(根据虚拟机策略)。

xxx.join //放弃当前线程的执行,先让xxx线程执行完,再自己执行。

10.减少锁的竞争

减小锁的范围,把不需要同步的代码移出锁的范围,耗时操作不要再同步代码中使用。

减小锁的粒度,不同变量使用不同的锁。

使用分段锁,集合可以使用分段锁,几个元素使用一个锁。下标%锁个数表示使用的锁。

避免热点域,例如在map中维护一个size来统计数量,那么每次操作都要同步size,那么这个size就是热点域,可以每个分段锁维护一个size,总数量是每个分段锁的size总和。

使用读写锁代替独占锁,读锁可重入,写锁独占。

谨慎使用对象池,通常同步开销比对象分配开销大。

11.原子变量(乐观锁-CAS)

一共有12个原子变量,可分为四组:标量类,更新器,数组类,复合变量类。

标量类:AtomicXXX

AtomicReference<T>则对应普通的对象引用,底层使用的compareAndSwapObject实现CAS,比较的是两个对象的地址是否相等。

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

推荐阅读更多精彩内容