线程安全性-原子性之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 ...
随机推荐
- Python程序的流程
1 """ 2 python程序的流程 3 """ 4 # ------------- 分支结构---------------- 5 # i ...
- XXE漏洞——介绍及利用
什么是xxe XML外部实体注入,简称XXE漏洞.XML文档结构包括XML声明,DTD文档类型定义,文档元素. XML示例 <?xml version="1.0"?>X ...
- JavaSE常用类之Object类
1. hashCode方法 代码: package NeiBuLei; public class hashCode { public static void main(String[] args) { ...
- 聊聊UI自动化的PageObject设计模式
当我们开发UI自动化测试用例时,需要引用页面中的元素(数据)才能够进行点击(动作)并显示出页面内容.如果我们开发的用例是直接对HTML元素进行操作,则这样的用例无法"应对"页面中U ...
- Codeforces Round #707 (Div. 2)A.英语漏洞 + C.Going Home C题收获不小
A题英语漏洞 A题传送门: https://codeforces.com/contest/1501/problem/A 其实题目说的很明白, 只是我傻傻的会错了意, 话不多说, 开整. 前两行是说, ...
- 2021-01-25 cf #697 Div3 C题(超时,换思路减少复杂度)
题目链接:https://codeforces.com/contest/1475/problem/C 题意要求:需组成的2对,男的序号不能重,女的序号不能重 比如这例 输入: 行1--测试个数 行1` ...
- 字符串/16进制/ASCII码的转换
1 /// <字符串转16进制格式,不够自动前面补零> 2 /// 假设文本框里面填写的是:01 02 03 04 05 06 3 /// Str获取的是01 02 03 04 05 06 ...
- 如何向开源项目(Apache-InLong)提交代码
目录 1 - 认领或提交 ISSUE 2 - clone 代码,本地编译安装 3 - 代码规范 4 - 提交代码 版权声明 Apache InLong(应龙)是一个一站式海量数据集成框架, 提供自动. ...
- kali 更换国内源
打开source源 vim /etc/apt/sources.list 没有权限进行更改 获取root 权限 按 i 提示内容: E325: 注意 发现交换文件 "/var/tmp/sour ...
- [洛谷] P2241 统计方形(数据加强版)
点击查看代码 #include<bits/stdc++.h> using namespace std; long long n, m, total, sum1, sum2; int mai ...