线程安全性-原子性之synchronized锁
原子性提供了互斥访问:同一时刻只能有一个线程进行操作;
除了Atomic包类之外,还有锁可以实现此功能;
synchronized: java关键字,依赖于jvm实现锁功能,被此关键字所修饰的,都是在同一时刻,只能有一个线程操作;
Lock: 由jdk提供的锁,Lock类,比如ReentranLock等..;
这次针对synchronized进行介绍:synchronized是一种同步锁,修饰对象有四种;
一,修饰代码块:大括号括起来的代码,作用于调用的对象,被修饰的代码称为同步语句块。
二,整个方法,作用于调用的对象,被修饰的方法称为同步方法。
三,整个静态方法,作用于所有对象。
四,修饰类,synchronized后面括号括起来的部分,作用于所有对象。
package com.example.concurrency.example.sync;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @author xiaozhuang
* @date 2022年04月08日 14:47
*/
@Slf4j
public class SynchronizedExample1 {
// 修饰代码块 作用于调用的对象
public void test1(){
synchronized (this){
for (int i = 0; i < 3; i++) {
log.info("修饰代码块:{}",i);
}
}
}
public static void main(String[] args) {
SynchronizedExample1 synchronizedExample1=new SynchronizedExample1();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(()->{
synchronizedExample1.test1();
});
executorService.execute(()->{
synchronizedExample1.test1();
});
executorService.shutdown();
}
}
先看看修饰代码块的例子,它是作用于调用的对象,这里我们根据对象 在线程池中调用了2次,test1方法,看一下输出

再改为两个对象调用时


发现它是交替按顺序输出的,它是作用于调用对象,所以不用对象调用之间是相互不影响的,在上面一个对象调用两次test1方法,则是需要一个执行完再执行另一个。
再看看修饰方法,也是作用于调用对象:


再看看两个对象调用时

可以看到输出是与上面的修饰代码块是一样;
可以得出一个结论:如果一个方法内部一整个都是同步代码块,那么它与用synchronized修饰的方法是等同的。
如果当前类是父类,当子类继承父类时,调用父类被synchronized修饰的方法时,是不会带上synchronized关键字的,需要自己手动加上去,synchronized不属于方法声明部分;
再看看修饰静态方法与修饰类的:


这里因为修饰类与修饰静态方法的作用于所有的对象,所以在这个类里,都是需要逐个执行完毕;
结论:如果一个方法里,一整个都是被synchronized所修饰的类包围的时候,那么它与被synchronized修饰的静态方法的作用是等同的。
通过上面对synchronized的了解,所以一个计数的问题也就迎刃而解了;
@Slf4j
public class ConcurrencyTest {
// 请求访问总数
public static int clientTotal = 5000;
// 同时并发执行的线程数
public static int threadTotal = 200;
// 计数的值
public static int count = 0;
public static void main(String[] args) throws InterruptedException {
// 线程池
ExecutorService executorService = Executors.newCachedThreadPool();
// 信号量 参数为 运行并发的数目
final Semaphore semaphore = new Semaphore(threadTotal);
// 递减计数器 参数为 请求数量 没执行成功一次会 减1
final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
for (int i = 0; i < clientTotal; i++) {
// 讲请求放入线程池中
executorService.execute(() -> {
try {
//判断信号量 判断当前线程是否允许被执行
semaphore.acquire();
add();
// 释放进程
semaphore.release();
} catch (Exception e) {
log.error("exception", e);
}
// 没执行完一次 计算器-1
countDownLatch.countDown();
});
}
countDownLatch.await();
// 关闭线程池
executorService.shutdown();
log.info("count:{}", count);
}
private static void add() {
count++;
}
}
只需要在add()方法加上synchronized,就会变成线程安全了;
最后对比一下synchronized,Lock,Atomic三者的区别:
synchronized:在执行到synchronized作用范围内的时候,它是不可中断的,必须等待代码执行完毕。适合竞争不激烈,可读性好,竞争激烈时,性能下降较快;
Lock:是可以中断的,只需要调用unLock就行,多样化同步,竞争激烈时能维持常态;
Atomic: 竞争激烈时能维持常态,比Lock性能好; 缺点就是只能同步一个值;
线程安全性-原子性之synchronized锁的更多相关文章
- Java并发编程入门与高并发面试(三):线程安全性-原子性-CAS(CAS的ABA问题)
摘要:本文介绍线程的安全性,原子性,java.lang.Number包下的类与CAS操作,synchronized锁,和原子性操作各方法间的对比. 线程安全性 线程安全? 线程安全性? 原子性 Ato ...
- 4-3 线程安全性-原子性-synchronized
原子性它提供了互斥访问,同一时刻只能有一个线程来对它进行操作.能保证同一时刻只有一个线程来对其进行操作的,除了Atomic包之外,还有锁.JDK提供锁主要分两种,synchronized是一个Java ...
- 并发与高并发(八)-线程安全性-原子性-synchronized
前言 闲暇时刻,谈一下曾经在多线程教程中接触的同步锁synchronized,相当于复习一遍吧. 主要介绍 synchronized:依赖JVM Lock:依赖特殊的CPU指令,代码实现,Reetra ...
- 并发与高并发(七)-线程安全性-原子性-atomic
一.线程安全性定义 定义:当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程 ...
- 线程安全性-原子性之Atomic包
先了解什么是线程安全性:当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称为这个类是线程 ...
- java多线程中篇(二) —— 线程的创建和Synchronized锁关键字
学习之前,先了解线程状态图 说明:线程共包括以下5种状态. 1. 新建状态(New) : 线程对象被创建后,就进入了新建状态.例如,Thread thread = new Thread ...
- 4-2 线程安全性-原子性-atomic-2
AtomicReference和AtomicLong.AtomicInteger很像,方法也基本上是一样的,然后我们通过引用Integer来做一个简单的例子. com.mmall.concurrenc ...
- Java线程安全性-原子性工具对比
synchronized 不可中断锁,适合竞争不激烈的场景,可读性好,竞争激烈时性能下降很快 Lock 可中断锁,多样化同步,竞争激烈时能维持常态 Atomic 竞争激烈时能维持常态,比Lock性能还 ...
- 4-1 线程安全性-原子性-atomic-1
我们发现在不做任何同步的情况下,我们计算的累加结果是错误的. com.mmall.concurrency.example.count.CountExample2 C:\Users\ZHONGZHENH ...
随机推荐
- 微信h5支付/jsapi支付/小程序支付
一. 介绍------------------------------------------------------------------ 微信支付官方开发文档: https://pay.wei ...
- 通过CSS给图像设置圆角边框
<html> <style> .smaller-image{ border-radius: 50%; width: 100px; } </style> <bo ...
- 面试问题整理之flex 布局
- 【版本2020.03】使用idea导入maven项目
心得1:不同版本的idea,一些选项的名称稍微有点不同,比如以前导入项目的选项名称都是import Project,但是我使用的版本是2020.03 导入项目的名称是 import Settings ...
- Postman大势已去
作为一名前端,日常开发过程中除了写业务代码,前后端联调更是重要的一环.但这一环却往往是整个开发中最繁琐也最累人的一环.任谁都想早点下班,然而提升联调效率并不是个纯技术相关的问题,而是需要有良好工作流程 ...
- 设置网站标题时找不到index.html问题解决
都知道,修改网站标题在根目录index.html里修改.但是在vue3更新后,index.html就没有放这里了,放到了public中.去public中一眼就能看到.我也是去那里就找到了.
- CTF中的一些图形密码
1.传统猪圈密码 猪圈密码又称为亦称朱高密码.共济会暗号.共济会密码或共济会员密码:是一种以特定符号来替换字母的加密方式 在线解密网址:http://moersima.00cha.net/zhuqua ...
- Java基础语法Day_07(1-3 常用API第一部分)
常用API第一部分 第1节 Scanner类 day07_01_API概述和使用步骤(使用最基本的三个步骤 搜索 构造方法 方法) day07_02_Scanner概述及其API文档 ...
- 基于SqlSugar的数据库访问处理的封装,支持.net FrameWork和.net core的项目调用
由于我们有时候需要在基于.net framework的项目上使用(如Winform端应用),有时候有需要在.net core的项目上使用(如.net core的WebAPI),那么我们把基于SQLSu ...
- springboot简单发送邮件介绍
1.新建一个springboot项目 2.所需要的的jar包: <dependency> <groupId>org.springframework.boot</group ...