Java并发之synchronized关键字和Lock接口
欢迎点赞阅读,一同学习交流,有疑问请留言 。
GitHub上也有开源 JavaHouse,欢迎star
引用
当开发过程中,我们遇到并发问题。怎么解决?
一种解决方式,简单粗暴:上锁。将千军万马都给拦下来,只允许一个人过独木桥。书面意思就是将并行的程序变成串行的程序。现实的锁有门锁、挂锁和抽屉锁等等。在Java中,我们的锁就是synchronized关键字和Lock接口。
synchronized关键字
synchronized也叫同步锁,是Java里面的关键字。我们可以猜测到synchronized原理也JVM虚拟机有关联。
synchronized锁的是对象。对象里面有一个叫做监视锁(monitor)的东西,监视锁依赖操作系统的互斥锁(Mutex Lock)。操作系统切换线程其实就是从用户态编程核心态(cpu的两种状态)。这个代价有点高,所以synchronized这个重量级锁后面也引进了偏向锁和轻量级锁。
加锁(监视锁monitor)过程分析():
- 当monitor的进入数为0,线程A进入
- monitor的进入数为1
- 线程B想进入该monitor就会被阻塞。
线程A可以重复进入该monitor,所以synchronized是可重入锁,和Lock实现的锁一样。
- 程序验证
public class SynchronizedTest {
private static int i = 0;
public static void main(String[] args) {
test();
}
public static void test(){
synchronized (SynchronizedTest.class){
synchronized (SynchronizedTest.class){
i++;
}
}
}
}
- 运行结果
程序正常运行,没有报错
synchronized可以修饰方法以及代码块,代码块就是上面重入锁的例子。
- 修饰方法
public class SynchronizedTest {
static int n = 100;
final static CountDownLatch start = new CountDownLatch(n);
private static int i = 0;
public static void main(String[] args) throws InterruptedException {
for (int j = 0; j < n; j++) {
Thread thread = new Thread(new addNoSynchronized());
thread.start();
}
start.await();
System.out.println(i);
}
public static class addSynchronized implements Runnable{
@Override
public void run() {
addSynchronized();
}
public static synchronized void addSynchronized(){
for (int j = 0; j < 1000; j++) {
i++;
}
start.countDown();
}
}
}
- 运行结果
100000
如果去掉 synchronized 关键字的话,运行结果大概率不是 100000,因为线程不安全问题。
Lock接口
一般我们使用 ReentrantLock 类作为重入锁,实现Lock接口。
- 使用方法
public class ReentranLockTest {
private static int j;
private static int n = 100;
private static CountDownLatch latch = new CountDownLatch(n);
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < n; i++) {
new Thread(new LockTest()).start();
}
latch.await();
System.out.println("结果为:"+j);
}
public static class LockTest implements Runnable{
static Lock lock = new ReentrantLock();
@Override
public void run() {
lockTest();
latch.countDown();
}
private void lockTest() {
lock.lock();
try {
for (int i = 0; i < 1000; i++) {
j++;
}
}finally {
lock.unlock();
}
}
}
}
- 运行结果
结果为:100000
这里我们锁住的 j++ 这块资源区(公共资源),lock 是 static 关键字修饰的,是类对象,思考一下如果不是类对象会怎么样?那就是连环锁了(看图)。
每一个线程都对可以用钥匙解开这把锁,对于程序而言,加锁操作就没有意义了。因为我们需要的是一个锁。
欢迎关注我的微信公众号
Java并发之synchronized关键字和Lock接口的更多相关文章
- Java并发之synchronized关键字深度解析(二)
前言 本文继续[Java并发之synchronized关键字深度解析(一)]一文而来,着重介绍synchronized几种锁的特性. 一.对象头结构及锁状态标识 synchronized关键字是如何实 ...
- synchronized关键字,Lock接口以及可重入锁ReentrantLock
多线程环境下,必须考虑线程同步的问题,这是因为多个线程同时访问变量或者资源时会有线程争用,比如A线程读取了一个变量,B线程也读取了这个变量,然后他们同时对这个变量做了修改,写回到内存中,由于是同时做修 ...
- Java多线程:synchronized关键字和Lock
一.synchronized synchronized关键字可以用于声明方法,也可以用来声明代码块,下面分别看一下具体的场景(摘抄自<大型网站系统与Java中间件实践>) 案例一:其中fo ...
- Java并发之synchronized关键字深度解析(一)
前言 近期研读路神之绝世武学,徜徉于浩瀚无垠知识之海洋,偶有攫取吉光片羽,惶恐未领略其精髓即隐入岁月深处,遂急忙记录一二,顺备来日吹cow之谈资.本小系列为并发之亲儿子-独臂狂侠synchronize ...
- 线程中synchronized关键字和lock接口的异同
一.synchronized关键字 1.可以用来修饰代码块 synchronized (this) { // 同步的关键字 this 表示当前线程对象 if (num == 0) { break; } ...
- Java并发之synchronized关键字
上篇文章我们主要介绍了并发的基本思想以及线程的基本知识,通过多线程我们可以实现对计算机资源的充分利用,但是在最后我们也说明了多线程给程序带来的两种典型的问题,针对它们,synchronize ...
- Java并发之synchronized关键字深度解析(三)
前言 本篇主要介绍一下synchronized的批量重偏向和批量撤销机制,属于深水区,大家提前备好氧气瓶. 上一篇说完synchronized锁的膨胀过程,下面我们再延伸一下synchronized锁 ...
- 深入理解Java并发之synchronized实现原理
深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入 ...
- 并发之synchronized关键字的应用
并发之synchronized关键字的应用 synchronized关键字理论基础 前两章我们学习了下java内存模型的相关知识, 现在我们来讲讲逢并发必出现的synchronized关键字. 作用 ...
随机推荐
- python之ORM(对象关系映射)
实现了数据模型与数据库的解耦,通过简单的配置就可以轻松更换数据库,而不需要更改代码.orm操作本质上会根据对接的数据库引擎,翻译成对应的sql语句.所有使用Django开发的项目无需关心程序底层使用的 ...
- python *args,**kwargs参数
实际上,关键的是*和** 我们以三个例子来解释: 普通的使用参数: def test1(arg): print(arg) test1("a") 输出: a *是将剩下的参数用元祖表 ...
- Pandas | 17 缺失数据处理
数据丢失(缺失)在现实生活中总是一个问题. 机器学习和数据挖掘等领域由于数据缺失导致的数据质量差,在模型预测的准确性上面临着严重的问题. 在这些领域,缺失值处理是使模型更加准确和有效的重点. 使用重构 ...
- 过滤器、拦截器和AOP的分析与对比
目录 一.过滤器(Filter) 1.1 简介 1.2 应用场景 1.3 源码分析 二.拦截器(Interceptor) 2.1 简介 2.2 应用场景 2.2 源码分析 三.面向切面编程(AOP) ...
- Spring Cloud gateway 网关服务二 断言、过滤器
微服务当前这么火爆的程度,如果不能学会一种微服务框架技术.怎么能升职加薪,增加简历的筹码?spring cloud 和 Dubbo 需要单独学习.说没有时间?没有精力?要学俩个框架?而Spring C ...
- 使用linq实现回调函数
通过输入的Id找到parentId是该Id的列表,然后找到parentId是上面那个Id的列表,以此类推,找到第一目录下所有子目录的的列表. 通过传入第一目录的Id,得到该目录下的所有子目录. 通过回 ...
- 第三十二章 System V信号量(三)
n哲学家进餐问题描述有五个哲学家,他们的生活方式是交替地进行思考和进餐,n哲学家们共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,n平时哲学家进行思考,饥饿时便试图取其左.右最靠近 ...
- 不用循环控制、条件控制、三目运算符 实现阶乘n!
long func(int n) { ( n <= 1 && (n=1) ) || ( n*=func(n-1)); return n; } template<int N& ...
- 前端技术之:JavaScript Test 断言库
expect 声称可以写更好的断言. https://github.com/mjackson/expect chai 可以写BDD样式的断言,也可以写TDD样式的断言,可用于Node.js与浏览器 ...
- 微信小程序的canvas和遮盖布颜色设置问题
canvas绘画出并显示小程序的逻辑首先是将网络图片转化为本地图片,其次再将进行绘画.将本地图片和二维码显示在画布上,最后将整个画布截图用api显示在屏幕上.真正的画图让他飞去屏幕外. 有时候会需要用 ...