一、概念

利用锁机制实现线程同步,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对象锁,锁的类型不同。

Java核心复习——synchronized的更多相关文章

  1. Java核心复习—— 原子性、有序性与Happens-Before

    一. 产生并发Bug的源头 可见性 缓存导致的可见性问题 原子性 线程切换带来的原子性问题 有序性 编译优化带来的有序性问题 上面讲到了 volatile 与可见性,本章再主要讲下原子性.有序性与Ha ...

  2. Java核心复习——J.U.C AbstractQueuedSynchronizer

    第一眼看到AbstractQueuedSynchronizer,通常都会有这几个问题. AbstractQueuedSynchronizer为什么要搞这么一个类? 这个类是干什么的.有什么用? 这个类 ...

  3. Java核心复习——线程池ThreadPoolExecutor源码分析

    一.线程池的介绍 线程池一种性能优化的重要手段.优化点在于创建线程和销毁线程会带来资源和时间上的消耗,而且线程池可以对线程进行管理,则可以减少这种损耗. 使用线程池的好处如下: 降低资源的消耗 提高响 ...

  4. Java核心复习—— ThreadLocal源码分析

    ThreadLocal,叫做线程本地存储,也可以叫做线程本地变量.ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量. 一.如何使用 class Acce ...

  5. Java核心复习 —— J.U.C 并发工具类

    一.CountDownLatch 文档描述 A synchronization aid that allows one or more threads to wait until* a set of ...

  6. Java核心复习—— volatile 与可见性

    一.介绍 volatile保证共享变量的"可见性".可见性指的是当一个线程修改变量时,另一个线程能读到这个修改的值. 这里就要提出几个问题. 问题1:为什么一个线程修改时,另一个线 ...

  7. Java核心复习——CompletableFuture

    介绍 JDK1.8引入CompletableFuture类. 使用方法 public class CompletableFutureTest { private static ExecutorServ ...

  8. Java核心复习——J.U.C LinkedBlockingQueue源码分析

    参考文档 LinkedBlockingQueue和ArrayBlockingQueue的异同

  9. Java核心复习——J.U.C ArrayBlockingQueue源码分析

    介绍 依赖关系 源码 构造方法 public ArrayBlockingQueue(int capacity) { this(capacity, false);//默认构造非公平的有界队列 } pub ...

随机推荐

  1. restTemplate源码解析(目录)

    restTemplate是spring实现的,基于restful风格的http请求模板.使用restTemplate可以简化请求操作的复杂性,同时规范了代码风格.本系列文章,将根据以下目录顺序,从源码 ...

  2. iOS 中各种横竖屏切换总结

    iOS 中横竖屏切换的功能,在开发iOS app中总能遇到.以前看过几次,感觉简单,但是没有敲过代码实现,最近又碰到了,demo尝试了几种情况,这里就做下总结.注意 横屏两种情况是反的你知道吗? UI ...

  3. jquery sortable的拖动方法示例详解

    转自:https://hb-keepmoving.iteye.com/blog/1154618 所有的事件回调函数都有两个参数:event和ui,浏览器自有event对象,和经过封装的ui对象   u ...

  4. 本文可能是国内第一篇介绍C/4HANA Foundation的中文博客

    SAP C/4HANA从去年发布已经过去了一年多的时间,C/4HANA的从业者,对于这五朵云里包含的产品集,想必都有了一些了解. Jerry注意到,SAP C/4HANA Foundation这个概念 ...

  5. lumen添加自定义异常

    在公用工具类写异常类 <?php namespace Brady\Tool\Exception; use Brady\Tool\Constant\ErrorMsg; use \Exception ...

  6. Java中关于String类型的一些思考

    作为初学者在学习Java的时候,变量类型是不可避免会遇到的,在以往我们的印象中字符串String都是作为基本类型而存在的,但是在Java中String类型确是一个实实在在的引用类型,是可以通过new关 ...

  7. linux网络编程之socket编程(十六)

    继续学习socket编程,今天的内容会有些难以理解,一步步来分解,也就不难了,正入正题: 实际上sockpair有点像之前linux系统编程中学习的pipe匿名管道,匿名管道它是半双工的,只能用于亲缘 ...

  8. 进程、requests模块的简单使用

    一.进程 1.进程间数据不共享 import multiprocessing data_list = [] def task(arg): data_list.append(arg) print(dat ...

  9. 面向对象中特殊方法的补充、isinstance/issubclass/type、方法和函数、反射

    一.面向对象中特殊方法的补充 1.__str__ 能将对象名改成你想要的字符串,但是类型还是类 class Foo(object): def __init__(self): pass def func ...

  10. 【转】Python源码学习Schedule

    原文:https://www.cnblogs.com/angrycode/p/11433283.html ----------------------------------------------- ...