内容简介:在JAVA中有很多锁,都可以实现多线程编程中实现数据的锁定,防止并发问题,本章节主要简单介绍下
# JAVA锁之一(synchronized快速记忆法)
一· 概述
在 JAVA 中有很多锁,都可以实现多线程编程中实现数据的锁定,防止并发问题,本章节主要简单介绍下 synchronized
.
二· 介绍
2.1 修饰场景
synchronized
是用于修饰用的加锁关键词,可以用于方法和代码块中,可以简单理解为锁住对象对应的指针地址,只要区分好指针对象是否同一个地址,就可以判断两个线程的锁是否互斥。
synchronized
是可重入的,意思就是当前线程获得锁之后,其他线程就无法获得锁进入,但是当前线程自己还可以再次获得锁多次进入。
由于使用比较简单,下面就简单列举一张表格,表示锁的应用场景以及说明。
| 修饰对象 | 被锁住对象 | 是否全局唯一 | 简单例子 |
|---|---|---|---|
| 类的类型 | 类的类型 | √ |
synchronized(Example.class) {...}
, 全局锁,其他线程无法进入 |
| 类的实例 | 类的实例 | × |
synchronized(this){...}
或者 final A a = new A()
synchronized(a){...}
|
| 普通成员函数 | 类的实例 | × |
public synchronized void f() {...}
锁住类的实例 |
| 静态成员函数 | 类的类型 | √ |
public static synchronized void f() {...}
锁住类的类型 |
| (静态)成员变量 | 成员对象所指向的实例,一定要用final修饰,不然重新赋值后就不是同一个对象了 | × |
final (static) A a = new A()
synchronized(a){...}
|
快速记忆法:可以简单理解成锁住对象是对象指针值。
2.2 代码样例
以下的代码,请观察哪些是互斥的
// http://www.easysb.cn/2019/05/341.html
public class LockTest {
@Getter
private final A a = new A();
private static int TICK = 5;
public void bFun1() {
synchronized (a) {
int count = 0;
while (count++ < TICK) {
System.out.println("hello from LockTest::bFun1");
ThreadUtils.sleepQuitely(1000);
}
}
}
public void bFun2() {
synchronized (a.getClass()) {
int count = 0;
while (count++ < TICK) {
System.out.println("hello from LockTest::bFun2");
ThreadUtils.sleepQuitely(1000);
}
}
}
@Data
public static class A {
private final Object a = new Object();
private synchronized void aFun1() {
int count = 0;
while (count++ < TICK) {
System.out.println("hello from A::aFun1");
ThreadUtils.sleepQuitely(1000);
}
}
private void aFun2() {
synchronized(this) {
int count = 0;
while (count++ < TICK) {
System.out.println("hello from A::aFun2");
ThreadUtils.sleepQuitely(1000);
}
}
}
private synchronized static void aFun3() {
int count = 0;
while (count++ < TICK) {
System.out.println("hello from A::aFun3");
ThreadUtils.sleepQuitely(1000);
}
}
private synchronized static void aFun4() {
synchronized (A.class) {
int count = 0;
while (count++ < TICK) {
System.out.println("hello from A::aFun4");
ThreadUtils.sleepQuitely(1000);
}
}
}
}
public static void main(String[] args) {
LockTest t = new LockTest();
List<Thread> list = Lists.newArrayList();
list.add(new Thread(() -> {
t.bFun1();
}));
list.add(new Thread(() -> {
t.bFun2();
}));
list.add(new Thread(() -> {
t.getA().aFun1();
}));
list.add(new Thread(() -> {
t.getA().aFun2();
}));
list.add(new Thread(() -> {
t.getA().aFun3();
}));
list.add(new Thread(() -> {
t.getA().aFun4();
}));
for (Thread thread : list) {
thread.start();
}
ThreadUtils.sleepQuitely(1000 * 30);
}
}
按照上面地址的快速记忆理解方案,那么可以简单归纳如下:
-
LockTest::bFun1锁住的对象是成员变量a地址。 -
LockTest::bFun2锁住的对象是A的类对象a.getClass(),也就是A.class地址,是全局唯一的。 -
A::aFun1修饰普通成员函数,锁住类对象实例的地址,也就是a地址。 -
A::aFun2普通成员函数this,锁住类对象实例的地址,也就是a地址。 -
A::aFun3静态成员函数,锁住A的类对象,也就是A.class地址。 -
A::aFun4成员函数,锁住类对象实例的地址A.class,全局唯一。
从上可以看出互斥的方法如下:
-
实例
a地址:LockTest::bFun1,A::aFun1,A::aFun2 -
类对象
A.class地址:LockTest::bFun2,A::aFun3,A::aFun4
输出的结果可能有多种,以下是一种输出结果
hello from LockTest::bFun2 hello from LockTest::bFun1 hello from LockTest::bFun2 hello from LockTest::bFun1 hello from LockTest::bFun2 hello from LockTest::bFun1 hello from LockTest::bFun2 hello from LockTest::bFun1 hello from LockTest::bFun1 hello from LockTest::bFun2 hello from A::aFun2 hello from A::aFun4 hello from A::aFun4 hello from A::aFun2 hello from A::aFun4 hello from A::aFun2 hello from A::aFun2 hello from A::aFun4 hello from A::aFun4 hello from A::aFun2 hello from A::aFun1 hello from A::aFun3 hello from A::aFun1 hello from A::aFun3 hello from A::aFun3 hello from A::aFun1 hello from A::aFun3 hello from A::aFun1 hello from A::aFun1 hello from A::aFun3
以上所述就是小编给大家介绍的《JAVA锁之一(synchronized快速记忆法)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 跨平台开源卡片记忆工具 anki
- c++ 如何记忆映射一个巨大的矩阵?
- 如何快速记忆C语言运算符?
- 如何更容易记忆:JavaScript 类型与类型判断
- Git超实用总结,再也不怕记忆力不好了
- 基于长短期记忆网络的短时雷达外推算法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java Web开发实战经典(基础篇)
李兴华、王月清 / 清华大学出版社 / 2010-8 / 69.80元
本书用通俗易懂的语言和丰富多彩的实例,通过对Ajax、JavaScript、HTML等Web系统开发技术基础知识的讲解,并结合MVC设计模式的理念,详细讲述了使用JSP及Struts框架进行Web系统开发的相关技术。 全书分4部分共17章,内容包括Java Web开发简介,HTML、JavaScript简介,XML简介,Tomcat服务器的安装及配置,JSP基础语法,JSP内置对象,Java......一起来看看 《Java Web开发实战经典(基础篇)》 这本书的介绍吧!