一、概念

利用锁机制实现线程同步,synchronized关键字的底层交由了JVM通过C++来实现

Java中的锁有两大特性:

  • 互斥性

    • 同一时间,只允许一个线程持有某个对象锁。
  • 可见性
    • 锁释放前,线程对变量的修改,后面获得锁的线程可见。

可见性

JMM关于synchronized的两条规定:

  1. 线程解锁前,必须把共享变量的最新值刷新到主内存中

  2. 线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新获取最新的值(注意:加锁与解锁需要是同一把锁)

通过以上两点,可以看到synchronized能够实现可见性。

二、用法

synchronized修饰位置与锁的关系

  • 同步方法 —— 对象锁,当前实例对象
  • 静态同步方法 —— 类对象锁,当前对象的Class对象
  • 同步方法块 —— 对象锁,synchonized括号里配置的对象

public class SynchronizedDemo { private static int m = 0; private Object obj = new Object(); /**
* 修饰非静态方法
*/
public synchronized void m1() {
sleep(2);
m++;
} /**
* 修饰静态方法
*/
public synchronized static void m2() {
sleep(2);
m++;
} /**
* 同步代码块,对对象加锁
*/
public synchronized void m3() {
synchronized (this) {
sleep(2);
m++;
}
} public synchronized void m4() {
synchronized (obj) {
sleep(2);
m++;
}
} /**
* 同步代码块,对类加锁
*/
public synchronized void m5() {
synchronized (SynchronizedDemo.class) {
sleep(2);
m++;
}
} public static void sleep(int second) { try {
Thread.sleep(second * 1_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }

三、面试问题

同一个对象在A、B两个线程中分别访问该对象的两个同步方法writer和reader,是否会产生互斥?


class LockDemo{ int a = 0; public synchronized void writer(){
sleep(10);
a++;
} public synchronized void reader(){
int i = a;
} public static void main(String[] args) { Test test = new Test();
new Thread(() -> {
test.writer();
}).start(); sleep(1); new Thread(() -> {
test.reader();
}).start(); } }

答案:会。因为synchronized修饰的是方法,锁是对象锁,默认当前的对象作为锁的对象。只有当A释放锁之后,B才会获得对象的锁。

(1)如果是换成是不同对象呢?

不会互斥,因为锁的是对象,而不是方法

(2)如果writer、reader方法加上static修饰,两个线程中,类直接调用两个方法呢?

会互斥,因为锁的是Class对象。

(3)如果writer方法用static修饰,reader方法不用呢?

不会互斥。因为一个是对象锁,一个是Class对象锁,锁的类型不同。

最新文章

  1. WinXP/Win7/Win8本地用户配置文件迁移至域用户
  2. [Android]关于Installation error: INSTALL_PARSE_FAILED_MANIFEST_MALFORMED ,修改包名
  3. H3C qos 简单配置
  4. SQL Server 2012 T-SQL 新特性
  5. 设置root用户不保存终端历史记录到.bash_history
  6. Theano2.1.3-基础知识之更多的例子
  7. JS Questions:Front-end Developer Interview Questions
  8. SequenceSum
  9. Scala IDE for Eclipse的下载、安装和WordCount的初步使用(本地模式和集群模式)
  10. zend studio 9.0.4 安装破解
  11. SharePoint REST api
  12. ural 1020 Rope
  13. 大数据笔记11:MapReduce的运行流程
  14. PowerShell 远程管理之 about_Remote_Troubleshooting
  15. 使用canvas实现超绚丽的旋转正方形
  16. Linux下 Unison 实现文件双向同步
  17. mq_receive
  18. CheckForIllegalCrossThreadCalls = false 是干嘛的?
  19. Javascript Array 方法整理
  20. mysql开通tcp远程连接

热门文章

  1. Java 之 递归
  2. Android NDK 学习之调用Java函数
  3. 【完整篇】orangepi香橙派新手入门之被官方坑
  4. axios使用API
  5. c# 克隆来创建对象副本
  6. Makefile中 的 phony target,empty target
  7. HTML&CSS基础-相对定位
  8. 解密Redis持久化【翻译】
  9. Mybatis3.0-[tp_28-29]-映射文件-resultMap_自定义结果集映射规则_及关联环境的搭建
  10. Wide & Deep Learning for Recommender Systems