设为首页 - 加入收藏
广告 1000x90
您的当前位置:幸运彩票注册 > 幸运飞艇 > 正文

java并发编程实战笔记(部分实战未看,老旧章节跳过)

来源:未知 编辑:admin 时间:2018-02-06
  • 3.shutdownNow的局限性:当强制关闭ExecutorService的时候,我们无法知道哪些任务正在运行,哪些任务还没运行。如果我们想保存此时的状态就无从下手此时我们可以实现AbstractExecutorService,然后将具体操作委托给一个ExecutorService,但是在实现中记录在shutdownNow时,还没执行的任务。
  • 3.处理非正常的线程终止

    • 1.一个线程在抛出异常之后,如果没进行处理就会被终止,虽然会报异常,但是我们通常很难被发觉
    • 2.解决1的一个方法是,在整个线程的最外面catch异常,然后处理异常。这种方式比直接结束整个程序好一点,但是有安全性问题因为这里抛出异常的时候可能整个程序会受影响。
    • 3.我们可以主动检测异常:通过实现Thread.UncaughtExceptionHandler接口,将未捕获的异常写入异常log之中,或者进行其他恢复性的操作
    • 4.只有通过execute提交任务,才会进行3中的方式。如果通过submit,那么程序会认为异常是返回的一部分,如用submit执行一个Future

    4.JVM关闭

    • 1.关闭钩子:通过Runtime.addShutdownHook注册的一系列清理线程将会被调用进行资源的清理。
      • 1.如果此时还有线程在执行,那么所有线程会并发执行。
      • 2.当所有钩子线程执行完毕,jvm会运行终结器。
      • 3.如果终结器或钩子线程没有执行完,那么关闭进程将会被挂起,此时jvm需要被强行关闭
      • 4.jvm被强行关闭时,应用线程会被强行结束,但是钩子线程不会被关闭
    • 2.守护线程:这些线程不会影响jvm关闭

    避免活跃性危险

    1.死锁

    • 1.哲学家就餐问题:
      • 1.互斥条件:一个资源每次只能被一个进程使用。
      • 2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
      • 3.不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
      • 4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

    2.死锁的避免和诊断

    • 1.支持定时锁:使用Lock代替内置锁,可以指定一个获取锁等待的时限
    • 2.通过线程转储来分析死锁

    3.其他活跃性危险

    • 1.饥饿:一个线程很长时间访问不到其需要的资源,如对线程优先级设置不对,导致一个线程很长时间获取不到cpu时间片
    • 2.活锁

    性能与可伸缩性

    1.线程引入的开销

    • 1.上下文切换:线程被阻塞会被JVM挂起,如果经常阻塞则无法完整调度时间片,从而增加上下文切换的时间
    • 2.内存同步:使用synchronized或者volatile关键字会将所有线程的本地缓存刷新,此时会消耗时间
    • 3.阻塞:线程被阻塞会被挂起,此时就会多了两个上下文切换的时间,所以少阻塞

    2.减少锁的竞争

    • 三种方法降低锁的竞争程度:1.减少锁持有时间 2.降低锁请求频率 3.使用可协调的独占锁
    • 1.缩小锁范围:将临界区的代码数量降到最小,尤其是io操作等会阻塞线程的操作
    • 2.减小锁的粒度:减少线程请求同一把锁的频率,也就是将锁分解成多个锁
    • 3.锁分段:将一个竞争激烈的锁分成多个锁,可能还是会竞争很激烈。将一组独立对象上的锁进行分解,被称为锁分段,如将一个Map桶让16个锁保护一个锁保护N/16个桶,那么并发写的性能就能提升16倍。这样的坏处就是:独占访问需要获取多个锁,更困难,开销更大
    • 4.避免热点域?
    • 5.一些代替独占锁的方式:并发容器、读写锁、不可变对象和原子变量

    显式锁

    1.Lock和ReentrantLock

    • 1.Lock提供了可轮询、定时以及中断锁获取的功能,其他方面和内置锁类似,需要在try final里面释放锁
    • 2.轮询锁和定时锁:可以通过tryLock来轮询避免,也可以通过定时锁来避免死锁

    2.公平性

    • 1.创建ReentrantLock的时候,可以设置锁的公平性,默认是非公平锁
      • 1.公平锁:按照线程排队的先后获取锁
      • 2.非公平锁:一个线程要获取锁,但还没放入请求锁的队列,此时锁可以用了,那么这个线程就可以插队
    • 2.内置锁和Lock之间的选择:内置锁简洁,Lock可以作为高级工具使用

    3.读写锁

    • 1.不对读读进行加锁,适用于大量读的操作

    原子变量与非阻塞同步机制

    1.锁的劣势

    • 1.一个线程因为锁的挂起和唤醒开销比较大。
    • 2.volatile是一种轻量级同步机制,但是如果需要依赖旧值,就会出现同步错误

    2.硬件对并发的支持

    • 1.独占锁是一种悲观锁,对于细粒度操作可以采用乐观的方式:在更新过程中判读是否有其他线程干扰,如果有这个操作就失败,而不是拒绝这个操作。
    • 2.比较交换:CAS指令可以检测其他线程的干扰,使得不用锁也可以实现原子的读-改-写操作
    • 3.java1.5后在底层实现了CAS操作,一些原子变量就是用的这个机制

    3.原子变量类

    • 1.原子变量是一种更好的volatile
    • 2.原子变量比锁的性能更好

    4.非阻塞算法

    • 实战,以后看

    什么是内存模型

    • 1.每个线程有自己的本地缓存,本地缓存有各个共享变量的副本,所有线程的缓存都会和主村进行双向通信,但不是实时的。
    • 2.为了让更多指令进行并发,在字节码编译和字节码转指令的时候会进行指令重排,也就是说没有必然先后关系的代码,最终运行的时候先后顺序是不一定的。
    • 3.代码的先后顺序有一个原则:Happens-Before
      • 1.程序顺序规则:程序中A在B前面,线程中A在B前面
      • 2.监视器锁规则:监视器锁的解锁必须在同一监视器锁加锁之前
      • 3.volatile规则:volatile变量写入操作必须在对该变量读操作之前
      • 4.线程启动规则:Thread#start()必须在该线程中任何操作之前
      • 5.线程结束规则:线程中所有操作都要在其他线程检测到该线程结束之前执行
      • 6.终结器规则:对象构造函数必须在启动该对象的终结器之前完成
      • 7.中断规则:线程1调用线程2的中断,必须在中断线程检测interrupt之前执行
      • 8.传递性:A在B前面,B在C前面,那么A在C前面
    上一篇:四大组件以及Application和Context的全面理解
    下一篇:没有了

    相关文章:

    相关推荐:

    网友评论:

    无法在这个位置找到: ajaxfeedback.htm
    栏目分类
    最新文章
    热门文章

    凤凰彩票 联系QQ: 邮箱:

    Copyright © 2002-2011 DEDECMS. 织梦科技 版权所有 Power by DedeCms

    Top