Tim

一枚野生程序员~

  • 主页
  • 分类
  • 标签
  • 归档
  • 关于
所有文章 工具

Tim

一枚野生程序员~

  • 主页
  • 分类
  • 标签
  • 归档
  • 关于

synchronized锁的是什么

阅读数:次 2020-03-28
字数统计: 1.3k字   |   阅读时长≈ 6分

最近发现synchronized锁的是什么?甚至有人认为synchronized锁的是代码??!这个我觉得还是很有必要通过实际的示例来说明synchronized锁的到底是什么。

根据获取的锁的分类:获取对象锁和获取类锁!

获取对象锁的两种用法

1、同步代码块(synchronized(this), synchronized(类实例对象)),锁是小括号()中的实例对象。
2、同步非静态方法(synchronized method),锁是当前对象的实例对象。

获取类锁的两种用法

1、同步代码块(synchronized(类.class)),锁是小括号()中的类对象,即Class对象。
2、同步静态方法(synchronized static method),锁是当前对象的类对象(Class对象)。

对象锁示例

看看这样一段代码:

SynchronizedDemo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package thread_study.synchronize;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class SynchronizedDemo implements Runnable{

@Override
public void run() {
String threadName = Thread.currentThread().getName();
if(threadName.startsWith("A")){
async();
}else if(threadName.startsWith("B")){
syncObjectBlock();
}else if(threadName.startsWith("C")){
syncObjectMethod();
}
}

private void async() {
try {
System.out.println(Thread.currentThread().getName()
+ "_Async_Start:"
+ new SimpleDateFormat("mm:ss").format(new Date()));

TimeUnit.SECONDS.sleep(1);

System.out.println(Thread.currentThread().getName()
+ "_Async_End:"
+ new SimpleDateFormat("mm:ss").format(new Date()));

} catch (InterruptedException e) {
e.printStackTrace();
}
}
private synchronized void syncObjectMethod() {
System.out.println(Thread.currentThread().getName()
+ "_SyncObjectMethod:"
+ new SimpleDateFormat("mm:ss").format(new Date()));

try {
System.out.println(Thread.currentThread().getName()
+ "_SyncObjectMethod_Start:"
+ new SimpleDateFormat("mm:ss").format(new Date()));

TimeUnit.SECONDS.sleep(1);

System.out.println(Thread.currentThread().getName()
+ "_SyncObjectMethod_End:"
+ new SimpleDateFormat("mm:ss").format(new Date()));

} catch (InterruptedException e) {
e.printStackTrace();
}
}

private void syncObjectBlock() {
System.out.println(Thread.currentThread().getName()
+ "_SyncObjectBlock:"
+ new SimpleDateFormat("mm:ss").format(new Date()));
synchronized (this){
try {
System.out.println(Thread.currentThread().getName()
+ "_SyncObjectBlock_Start:"
+ new SimpleDateFormat("mm:ss").format(new Date()));

TimeUnit.SECONDS.sleep(1);

System.out.println(Thread.currentThread().getName()
+ "_SyncObjectBlock_End:"
+ new SimpleDateFormat("mm:ss").format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

SynchronizedMain.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package thread_study.synchronize;

public class SynchronizedMain {
public static void main(String[] args) {
SynchronizedDemo demo = new SynchronizedDemo();
Thread A_thread1 = new Thread(demo, "A_thread1");
Thread A_thread2 = new Thread(demo, "A_thread2");
Thread B_thread1 = new Thread(demo, "B_thread1");
Thread B_thread2 = new Thread(demo, "B_thread2");
Thread C_thread1 = new Thread(demo, "C_thread1");
Thread C_thread2 = new Thread(demo, "C_thread2");
A_thread1.start();
A_thread2.start();

B_thread1.start();
B_thread2.start();

C_thread1.start();
C_thread2.start();
}
}

mark

但是如果我们传入不同的对象呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package thread_study.synchronize;

public class SynchronizedMain {
public static void main(String[] args) {
//SynchronizedDemo demo = new SynchronizedDemo();
Thread A_thread1 = new Thread(new SynchronizedDemo(), "A_thread1");
Thread A_thread2 = new Thread(new SynchronizedDemo(), "A_thread2");
Thread B_thread1 = new Thread(new SynchronizedDemo(), "B_thread1");
Thread B_thread2 = new Thread(new SynchronizedDemo(), "B_thread2");
Thread C_thread1 = new Thread(new SynchronizedDemo(), "C_thread1");
Thread C_thread2 = new Thread(new SynchronizedDemo(), "C_thread2");
A_thread1.start();
A_thread2.start();

B_thread1.start();
B_thread2.start();

C_thread1.start();
C_thread2.start();
}
}

mark

从上面的代码和结果中我们可以得出一个结论,那就是

获取对象锁的两种用法:
1、同步代码块(synchronized(this), synchronized(类实例对象)),锁是小括号()中的实例对象。
2、同步非静态方法(synchronized method),锁是当前对象的实例对象。

同步非静态方法锁住整个方法,而同步代码块只是锁住的只是方法中的一部分代码

获取类锁的两种用法
1、同步代码块(synchronized(类.class)),锁是小括号()中的类对象,即Class对象。
2、同步静态方法(synchronized static method),锁是当前对象的类对象(Class对象)。

同步静态方法锁住整个方法,而同步代码块只是锁住的只是方法中的一部分代码,与上面一样的

类锁示例

下面来看看同步静态方法和同步代码块(synchronized(类.class))的效果吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package thread_study.synchronize;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class SynchronizedDemo implements Runnable{

@Override
public void run() {
String threadName = Thread.currentThread().getName();
if(threadName.startsWith("A")){
async();
}else if(threadName.startsWith("B")){
syncObjectBlock();
}else if(threadName.startsWith("C")){
syncObjectMethod();
}else if(threadName.startsWith("D")){
syncClassBlock();
}else if(threadName.startsWith("E")){
syncClassMethod();
}
}

private synchronized static void syncClassMethod() {
System.out.println(Thread.currentThread().getName()
+ "_SyncClassMethod:"
+ new SimpleDateFormat("mm:ss").format(new Date()));
try {
System.out.println(Thread.currentThread().getName()
+ "_SyncClassMethod_Start:"
+ new SimpleDateFormat("mm:ss").format(new Date()));
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName()
+ "_SyncClassMethod_End:"
+ new SimpleDateFormat("mm:ss").format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}

private void syncClassBlock() {
System.out.println(Thread.currentThread().getName()
+ "_SyncClassBlock:"
+ new SimpleDateFormat("mm:ss").format(new Date()));
synchronized (SynchronizedDemo.class){
try {
System.out.println(Thread.currentThread().getName()
+ "_SyncClassBlock_Start:"
+ new SimpleDateFormat("mm:ss").format(new Date()));
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName()
+ "_SyncClassBlock_End:"
+ new SimpleDateFormat("mm:ss").format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

private void async() {
try {
System.out.println(Thread.currentThread().getName()
+ "_Async_Start:"
+ new SimpleDateFormat("mm:ss").format(new Date()));
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName()
+ "_Async_End:"
+ new SimpleDateFormat("mm:ss").format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//...和上面一样的
}

SynchronizedMain.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package thread_study.synchronize;

public class SynchronizedMain {
public static void main(String[] args) {
Thread A_thread1 = new Thread(new SynchronizedDemo(), "A_thread1");
Thread A_thread2 = new Thread(new SynchronizedDemo(), "A_thread2");
Thread D_thread1 = new Thread(new SynchronizedDemo(), "D_thread1");
Thread D_thread2 = new Thread(new SynchronizedDemo(), "D_thread2");
Thread E_thread1 = new Thread(new SynchronizedDemo(), "E_thread1");
Thread E_thread2 = new Thread(new SynchronizedDemo(), "E_thread2");

A_thread1.start();
A_thread2.start();

D_thread1.start();
D_thread2.start();
E_thread1.start();
E_thread2.start();
}
}

mark

对象锁和类锁不会干扰

最后看看类锁和对象锁是否会相互影响呢?

修改一下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package thread_study.synchronize;

public class SynchronizedMain {
public static void main(String[] args) {
//SynchronizedDemo demo = new SynchronizedDemo();
Thread A_thread1 = new Thread(new SynchronizedDemo(), "A_thread1");
Thread A_thread2 = new Thread(new SynchronizedDemo(), "A_thread2");
Thread B_thread1 = new Thread(new SynchronizedDemo(), "B_thread1");
Thread B_thread2 = new Thread(new SynchronizedDemo(), "B_thread2");
Thread C_thread1 = new Thread(new SynchronizedDemo(), "C_thread1");
Thread C_thread2 = new Thread(new SynchronizedDemo(), "C_thread2");
Thread D_thread1 = new Thread(new SynchronizedDemo(), "D_thread1");
Thread D_thread2 = new Thread(new SynchronizedDemo(), "D_thread2");
Thread E_thread1 = new Thread(new SynchronizedDemo(), "E_thread1");
Thread E_thread2 = new Thread(new SynchronizedDemo(), "E_thread2");

A_thread1.start();
A_thread2.start();

B_thread1.start();
B_thread2.start();
C_thread1.start();
C_thread2.start();

D_thread1.start();
D_thread2.start();
E_thread1.start();
E_thread2.start();
}
}

mark

可以看出来,类锁和对象锁是不会相互干扰的!

赏

谢谢你请我喝咖啡

支付宝
微信
  • 本文作者: Tim
  • 本文链接: https://zouchanglin.cn/3254260081.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 许可协议。转载请注明出处!
  • JavaSE
  • 多线程
  • 并发编程

扫一扫,分享到微信

synchronized实现与优化
线程相关的基础问题
  1. 1. 对象锁示例
  2. 2. 类锁示例
  3. 3. 对象锁和类锁不会干扰
© 2017-2021 Tim
本站总访问量次 | 本站访客数人
  • 所有文章
  • 工具

tag:

  • 生活
  • Android
  • 索引
  • MySQL
  • 组件通信
  • Nginx
  • JavaSE
  • JUC
  • JavaWeb
  • 模板引擎
  • 前端
  • Linux
  • 计算机网络
  • Docker
  • C/C++
  • JVM
  • 上传下载
  • JavaEE
  • SpringCloud
  • Golang
  • Gradle
  • 网络安全
  • 非对称加密
  • IDEA
  • SpringBoot
  • Jenkins
  • 字符串
  • vim
  • 存储
  • 文件下载
  • Mac
  • Windows
  • NIO
  • RPC
  • 集群
  • 微服务
  • SSH
  • 配置中心
  • XML
  • Chrome
  • 压力测试
  • Git
  • 博客
  • 概率论
  • 排序算法
  • 分布式
  • 异常处理
  • 文件系统
  • 哈希
  • openCV
  • 栈
  • 回溯
  • SpringCore
  • 流媒体
  • rtmp
  • 面向对象
  • Vue
  • ElementUI
  • 软件工程
  • 异步
  • 自定义UI
  • ORM框架
  • 模块化
  • 交互式
  • Jsoup
  • Http Client
  • LRUCache
  • RabbitMQ
  • 消息通信
  • 服务解耦
  • 负载均衡
  • 权限
  • 多线程
  • 单例模式
  • Protobuf
  • 序列化
  • Python
  • m3u8
  • 堆
  • 二叉树
  • 自定义View
  • 观察者模式
  • 设计模式
  • 线程池
  • 动态扩容
  • 高可用
  • GC
  • ffmpeg
  • SpringMVC
  • REST
  • Redis
  • 缓存中间件
  • UML
  • Maven
  • Netty
  • 高性能网络
  • IPC通信
  • IO
  • Stream
  • 发布订阅
  • SQLite
  • Hash
  • 集合框架
  • 链表
  • Lambda
  • 汇编语言
  • 组件化
  • Router
  • 开发工具

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia-plus根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 思维导图
  • PDF工具
  • 无损放大
  • 代码转图
  • HTTPS证书