zoukankan      html  css  js  c++  java
  • 【JUC】并发编程的艺术笔记

    1.单核处理器也支持多线程执行代码,使用CPU分配时间片来实现。

    2.上下文切换:任务从保存到再加载的过程。

    3.减少上下文切换(避免频繁切换任务):

    1)无锁并发编程。

    2)CAS算法。

    3)使用最少线程,避免创建不需要的线程。

    4)使用协程:单线程里实现多任务的调度。

    4.volatile轻量级的synchronized,保证了共享变量的可见性。

    5.线程在将volatile共享变量写回共享内存时,会有lock指令,通过MESI总线嗅探机制,每个线程嗅探总线上的变量根据缓存一致性协议,使他们工作空间的变量无效,必须重新去共享内存再一个取。

    6.volatile优化:将变量填充字节码到64字节,处理器的cache高速缓存行都是64字节,使用linkedTransferQueue定义了头节点和尾结点用来放置和拿取,填充字节码到64之后保证头尾结点 不会被同一高速缓存行锁定。

    7.sychronized重量级锁,使用方法:

    1)锁普通同步方法,锁当前实例对象

    2)锁静态同步方法,锁当前类的Class对象。

    3)同步方法块,锁括号里指定的对象。

    8.JVM基于进入和退出Monitor对象来实现同步,字节码monitorexit和monitorenter指令 是sychronized底层实现,字节码底层是操作系统的mutexLock互斥锁,因为Java的线程模型是和OS一一对映的,所以每次mutexLock都要引起 用户态内核态的切换 。每一个对象都有自己的监视器。

    9.Java的对象头(1,Mark Word 2,指向类的指针 3,数组长度(只有数组对象才有))

    mark word无锁条件下存储:hashcode 分代年龄 锁标记位。

    mark word对应锁的状态变化

    10.对象的结构(对象头 对象实例 填充字段)

    11.无锁:两种情况:不存在资源竞争,存在竞争但是只允许一个线程修改(CAS)实现无锁编程

    12.偏向锁:使用mark word来标识线程ID。

    运行过程中,同步锁只有一个线程访问,不存在多线程争用的情况,则线程是不需要触发同步的,这种情况下,就会给线程加一个偏向锁。

    如果在运行过程中,遇到了其他线程抢占锁,则持有偏向锁的线程会被挂起,JVM会消除它身上的偏向锁,将锁恢复到标准的轻量级锁。

    13.轻量级锁:

    1)其他线程竞争对象,会自旋(CPU轮询访问是否解锁了)。

    2)适应性自旋:根据上一个在锁上的自旋和锁状态 确定自旋时间。

    3)外面竞争的资源超过1个,升级为重量级锁。

    14.锁只能升级 不能降级。

    15.处理器保持原子操作:通过缓存、通过总线加锁。

    16.Java使用锁、循环CAS来保证原子性。

    17.CAS比较与替换,CAS使用处理器层面的指令完成原子操作。

    cas以及ABA问题:https://www.cnblogs.com/cckong/p/14444374.html

    18.悲观锁:操作系统认为如果不严格同步线程调用,就一定会出异常。所以只提供一个线程调用,而阻塞其他线程。

    乐观锁:操作系统认为不会被其他线程更改,所以不需要加锁。、

    19.运行Java程序时,启动一个Java进程,在进程中有很多线程比如用户线程main、守护线程gc等。

    20.设置线程优先级,但是具体还是要由操作系统决定。

     21.线程状态以及变化过程

    22.守护线程,守护线程的run方法代码块里不一定全部执行,因为JVM可能比执行更早退出。

    23.线程的中断机制:

    1)interrupt():设置中断标识位,正在运行的线程无法中断,在wait、sleep、jion的线程终止阻塞,抛出异常。

    2)isInterrupted():方法唯一的作用只是测试线程是否已经中断,中断标识位的状态并不受到该方法的影响。

    3)interrupted():方法的作用是测试当前线程是否已经中断,线程的中断标识位由该方法清除。

    24.sychronized竞争资源图

     25.sychronized加等待/通知机制的流程图

    wait/notify必须是同步块、同步方法里面的。

    调用wait方法,进入等待队列,状态也变为等待状态。

    调用notify方法,并不会马上放弃锁,要等运行完,才释放。

    notify是让一个线程从等待队列到同步队列,nitufyAll是让所以线程从等待队列到同步队列。

    同步队列上的线程状态为Blocked阻塞态。

     26.jion方法 让调用此方法的线程 插队执行。

     27.ThreadLocal 线程变量,以ThreadLocal对象为键,任意对象为值得储存结构(ThreadLocalMap类型)。

    应用:spring使用threadLocal保证单个线程中得数据库连接是同一个。

    28.锁 lock  提供了比synchronized更加灵活的加锁方式

    29.AQS队列同步器:构建锁以及其他同步组件的基础框架。同步器可以独占式也可以共享式获得同步状态。

    使用int变量来表示同步状态,以及内置的FIFO队列来完成线程的排队。

    重写同步器方法时需要用到 下面来访问、改变同步状态

    getState();//获得同步状态
    setState(int newStare);//设置当前同步状态
    compareAndSet(int expect,int update);//CAS设置当前状态
  • 相关阅读:
    作为字节跳动的面试官,有些话我不得不说!
    阿里面试 Java 都问什么?万字总结!
    离职10天,面挂4家公司!
    Nginx 又一牛 X 功能:流量拷贝
    金三银四铜五铁六,Offer收到手软!
    在阿里干了5年招聘,这10条建议我必须分享给你!
    nyoj 1238 最少换乘(dijkstra)
    hdu 1035 Robot Motion(模拟)
    网络工程 POST与GET请求方法的本质区别
    hdu 1279 验证角谷猜想(简单的模拟)
  • 原文地址:https://www.cnblogs.com/cckong/p/14619366.html
Copyright © 2011-2022 走看看