zoukankan      html  css  js  c++  java
  • Java 高并发之魂

    前置知识

    • 了解Java基本语法
    • 了解多线程基本知识

    知识介绍

    • Synchronized简介:作用、地位、不控制并发的后果
    • 两种用法:对象锁类锁
    • 多线程访问同步方法的7种情况:是否是static、Synchronized方法等
    • Synchronized的性质:可重入、不可中断
    • 原理:加解锁原理、可重入原理、可见性原理
    • Synchronized的缺陷:效率低、不够灵活、无法预判是否成功获取锁
    • 常见问题:
      • 如何选择Lock或Synchronized等
      • 如何提高性能、JVM如何解决那个线程获取锁等

    Synchronized简介

    作用

    官方解释

      同步方法支持一种简单的策略来防止线程干扰和内存一致性错误:如果一个对象对多个线程可见,则对该对象变量的所有读取或写入都是通过同步方法完成的。

    通俗易懂的解释

      能够保证在同一时刻最多只有一个线程执行该段代码,以达到保证并发安全的效果。

    地位

    • Synchronized是Java的关键字,被Java语言原生支持

    代码演示:不使用并发手段的后果演示

    代码实战:两个线程同时a++,最后结果会比预计的少

    原因

      count++,它看上去只是一个操作,实际上包含了三个动作:

    1. 读取count
    2. 将count加1
    3. 将count的值写入到内存中
    • 最基本的互斥同步手段
    • 并发编程中的元老级角色,是并发编程的必学内容

    Synchronized的两个用法

    对象锁

      包括方法锁(默认锁对象为this当前实例对象)和同步代码块锁(自己指定锁对象)

    代码块形式:手动指定锁对象

     

    方法锁形式:synchronized修饰普通方法,锁对象默认为this

     

     类锁

    概念(重要):Java类可能有很多个对象,但只有1个Class对象

    本质:所以所谓的类锁,不过是Class对象的锁而已

    用法和效果:类锁只能在同一时刻被一个对象拥有

    形式1:synchronized加载static方法上

    形式2:synchronized(*.class)代码块

     消失的请求解决方案

    不使用并发手段会有什么后果?如何解决?

     解决问题

      两个线程同时a++,最后结果会比预计的少

    原因

       count++,它看上去知识一个操作,实际上包含了三个动作

    1. 读取count
    2. 将count+1
    3. 将count的值写入到内存中

    方法一

     方法二

     方法三

    七种常见情况之123

    多线程访问同步方法的7种情况

    1. 两个线程同时访问一个对象的同步方法
    2. 两个线程访问的是两个对象的同步方法
    3. 两个线程访问的是synchronized的静态方法
    4. 同时访问同步方法与非同步方法
    5. 访问同一个对象的不同的普通同步方法
    6. 同时访问静态synchronized和非静态synchronized方法
    7. 方法抛异常后,会释放锁

    情况一:

     情况二:

     

     情况三:

     情况四:

     

     

     情况五:

     

     情况六:

     

     

    情况七:

     7种情况总结

     3点核心思想

    1.  一把锁只能同时被一个线程获取,没有拿到锁的线程必须等待(对应第1、5种情况)
    2. 每个实例都对应有自己的一把锁,不同实例之间互不影响;例外:锁对象锁是*.class以及Synchronized修饰的是static方法的时候,所有对象共用同一把锁(对应第2、3、4、6种情况);
    3. 无论是方法正常执行完毕或者方法抛出异常,都会释放锁(对应第7种情况)

    Synchronized缺陷

    • 效率低:锁的释放情况少、试图获得锁时不能设定超时、不能中断一个正在试图获得锁的线程
    • 不够灵活(读写锁更灵活):加锁和释放的时机单一,每个锁仅有单一的条件(某个对象),可能是不够的
    • 无法知道是否成功获取到锁

     常见面试问题

    1、使用注意点:锁对象不能为空、作用域不宜过大、避免死锁

    2、如何选择Lock和Synchronized关键字?

    3、多线程访问同步方法的各种具体情况

  • 相关阅读:
    Leetcode 191.位1的个数 By Python
    反向传播的推导
    Leetcode 268.缺失数字 By Python
    Leetcode 326.3的幂 By Python
    Leetcode 28.实现strStr() By Python
    Leetcode 7.反转整数 By Python
    Leetcode 125.验证回文串 By Python
    Leetcode 1.两数之和 By Python
    Hdoj 1008.Elevator 题解
    TZOJ 车辆拥挤相互往里走
  • 原文地址:https://www.cnblogs.com/chenyanbin/p/11796709.html
Copyright © 2011-2022 走看看