Java 高并发之魂
前置知识
- 了解Java基本语法
- 了解多线程基本知识
知识介绍
- Synchronized简介:作用、地位、不控制并发的后果
- 两种用法:对象锁和类锁
- 多线程访问同步方法的7种情况:是否是static、Synchronized方法等
- Synchronized的性质:可重入、不可中断
- 原理:加解锁原理、可重入原理、可见性原理
- Synchronized的缺陷:效率低、不够灵活、无法预判是否成功获取锁
- 常见问题:
- 如何选择Lock或Synchronized等
- 如何提高性能、JVM如何解决那个线程获取锁等
Synchronized简介
作用
官方解释
同步方法支持一种简单的策略来防止线程干扰和内存一致性错误:如果一个对象对多个线程可见,则对该对象变量的所有读取或写入都是通过同步方法完成的。
通俗易懂的解释
能够保证在同一时刻最多只有一个线程执行该段代码,以达到保证并发安全的效果。
地位
- Synchronized是Java的关键字,被Java语言原生支持
代码演示:不使用并发手段的后果演示
代码实战:两个线程同时a++,最后结果会比预计的少

原因
count++,它看上去只是一个操作,实际上包含了三个动作:
- 读取count
- 将count加1
- 将count的值写入到内存中
- 最基本的互斥同步手段
- 并发编程中的元老级角色,是并发编程的必学内容
Synchronized的两个用法
对象锁
包括方法锁(默认锁对象为this当前实例对象)和同步代码块锁(自己指定锁对象)
代码块形式:手动指定锁对象




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

类锁
概念(重要):Java类可能有很多个对象,但只有1个Class对象
本质:所以所谓的类锁,不过是Class对象的锁而已
用法和效果:类锁只能在同一时刻被一个对象拥有
形式1:synchronized加载static方法上

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

消失的请求解决方案
不使用并发手段会有什么后果?如何解决?
解决问题
两个线程同时a++,最后结果会比预计的少
原因
count++,它看上去知识一个操作,实际上包含了三个动作
- 读取count
- 将count+1
- 将count的值写入到内存中
方法一

方法二

方法三

七种常见情况之123
多线程访问同步方法的7种情况
- 两个线程同时访问一个对象的同步方法
- 两个线程访问的是两个对象的同步方法
- 两个线程访问的是synchronized的静态方法
- 同时访问同步方法与非同步方法
- 访问同一个对象的不同的普通同步方法
- 同时访问静态synchronized和非静态synchronized方法
- 方法抛异常后,会释放锁
情况一:

情况二:

情况三:

情况四:


情况五:


情况六:


情况七:

7种情况总结
3点核心思想
- 一把锁只能同时被一个线程获取,没有拿到锁的线程必须等待(对应第1、5种情况)
- 每个实例都对应有自己的一把锁,不同实例之间互不影响;例外:锁对象锁是*.class以及Synchronized修饰的是static方法的时候,所有对象共用同一把锁(对应第2、3、4、6种情况);
- 无论是方法正常执行完毕或者方法抛出异常,都会释放锁(对应第7种情况)
Synchronized缺陷
- 效率低:锁的释放情况少、试图获得锁时不能设定超时、不能中断一个正在试图获得锁的线程
- 不够灵活(读写锁更灵活):加锁和释放的时机单一,每个锁仅有单一的条件(某个对象),可能是不够的
- 无法知道是否成功获取到锁

常见面试问题
1、使用注意点:锁对象不能为空、作用域不宜过大、避免死锁
2、如何选择Lock和Synchronized关键字?
3、多线程访问同步方法的各种具体情况
Java 高并发之魂的更多相关文章
- Java高并发之锁优化
本文主要讲并行优化的几种方式, 其结构如下: 锁优化 减少锁的持有时间 例如避免给整个方法加锁 public synchronized void syncMethod(){ othercode1(); ...
- java高并发之线程池
Java高并发之线程池详解 线程池优势 在业务场景中, 如果一个对象创建销毁开销比较大, 那么此时建议池化对象进行管理. 例如线程, jdbc连接等等, 在高并发场景中, 如果可以复用之前销毁的对 ...
- java高并发之锁的使用以及原理浅析
锁像synchronized同步块一样,是一种线程同步机制.让自Java 5开始,java.util.concurrent.locks包提供了另一种方式实现线程同步机制——Lock.那么问题来了既然都 ...
- 1.6 JAVA高并发之线程池
一.JAVA高级并发 1.5JDK之后引入高级并发特性,大多数的特性在java.util.concurrent 包中,是专门用于多线程发编程的,充分利用了现代多处理器和多核心系统的功能以编写大规模并发 ...
- Java高并发之无锁与Atomic源码分析
目录 CAS原理 AtomicInteger Unsafe AtomicReference AtomicStampedReference AtomicIntegerArray AtomicIntege ...
- Java高并发之线程池详解
线程池优势 在业务场景中, 如果一个对象创建销毁开销比较大, 那么此时建议池化对象进行管理. 例如线程, jdbc连接等等, 在高并发场景中, 如果可以复用之前销毁的对象, 那么系统效率将大大提升. ...
- Java高并发之设计模式
本文主要讲解几种常见并行模式, 具体目录结构如下图. 单例 单例是最常见的一种设计模式, 一般用于全局对象管理, 比如xml配置读写之类的. 一般分为懒汉式, 饿汉式. 懒汉式: 方法上加synchr ...
- Java高并发之线程基本操作
结合上一篇同步异步,这篇理解线程操作. 1.新建线程.不止thread和runnable,Callable和Future了解一下 package com.thread; import java.tex ...
- Java高并发之同步异步
1.概念理解: 2.同步的解决方案: 1).基于代码 synchronized 关键字 修饰普通方法:作用于当前实例加锁,进入同步代码前要获得当前实例的锁. 修饰静态方法:作用于当前类对象加锁,进入同 ...
随机推荐
- .Net Core 商城微服务项目系列(七):使用消息队列(RabbitMQ)实现服务异步通信
RabbitMQ是什么,怎么使用我就不介绍了,大家可以到园子里搜一下教程.本篇的重点在于实现服务与服务之间的异步通信. 首先说一下为什么要使用消息队列来实现服务通信:1.提高接口并发能力. 2.保证 ...
- js中对于数组的操作
let myArray=[11,22,33]; console.log('原数组:',myArray); myArray.push(44,55); console.log('用push在数组后面插入元 ...
- 每个新手程序员都必须知道的Python技巧
当下,Python 比以往的任何时候都更加流行,人们每天都在实践着 Python 是多么的强大且易用. 我从事 Python 编程已经有几年时间了,但是最近6个月才是全职的.下面列举的这些事情,是我最 ...
- div模拟select/option解决兼容性问题及增加可拓展性
个人博客: http://mcchen.club 想到做这个模拟的原因是之前使用select>option标签的时候发现没有办法操控option的很多样式,比如line-height等,还会由此 ...
- 两台CentOS6.5 在不同机器上互联
准备工作 1.安装vmware及虚拟机centos6.5: 2.将安装好的centos6.5复制一份,在另一台机器上拷贝. 要进行不同机器上虚拟机的互相通信,需要用桥接模式进行互联.如下图,对vmwa ...
- 网络游戏开发-客户端2(自定义websocket协议格式)
Egret官方提供了一个Websocket的库,可以让我们方便的和服务器长连接交互. 标题写的时候自定义websocket的协议格式.解释一下,不是说我们去动websocket本身的东西,我们是在we ...
- Linux之常用命令II
一.VI编辑器 1) 概述 ◆ Visual Interface(可视化接口): ◆ 类似Windows中的记事本,比记事本强大: ◆ VIM相对于VI做了哪些提升 -VIM支持多级撤销 -VI ...
- 2019.10.26 CSP%您赛第三场
\(CSP\)凉心模拟^_^ --题源\(lqx.lhc\)等各位蒟蒻 题目名称 比赛 传递消息 开关灯 源文件名 \(competition.cpp\) \(message.cpp\) \(ligh ...
- 【python数据分析实战】电影票房数据分析(一)数据采集
目录 1.获取url 2.开始采集 3.存入mysql 本文是爬虫及可视化的练习项目,目标是爬取猫眼票房的全部数据并做可视化分析. 1.获取url 我们先打开猫眼票房http://piaofang.m ...
- Spring 基础知识学习
Spring 总结 在Spring框架的发布版本中,共包含了20个不同的模块,可以划分为6类不同的功能. Spring整体架构图 为了降低Java开发的复杂性,Spring采取了以下4种关键策略: 基 ...
