谈谈java中的synchronized关键字

1.synchronized的3种用法

public class Client {
    public static void main(String[] args) {
        testSynchronized();
    }

    private static void testSynchronized() {
        new Foo().sayHello();
    }
    static class Foo {
    //修饰代码块
    void sayHello() {
        synchronized (this) {
            System.out.println("hello");
        }
    }
    //修饰示例方法
    synchronized void sayGood(){
        System.out.println("good");
    }
    //修饰静态方法
    static synchronized void sayHi(){
        System.out.println("hi");
    }
  }
}

  

(1)修饰实例方法,作用于当前对象实例加锁,进入同步代码前要获得当前对象实例的锁
(2)修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁 。也就是给当前类加锁,会作
用于类的所有对象实例,因为静态成员不属于任何一个实例对象,是类成员( static 表明这是该类的一个静态
资源,不管new了多少个对象,只有一份,所以对该类的所有对象都加了锁)。所以如果一个线程A调用一个实
例对象的非静态 synchronized 方法,而线程B需要调用这个实例对象所属类的静态 synchronized 方法,是允
许的,不会发生互斥现象,因为访问静态 synchronized 方法占用的锁是当前类的锁,而访问非静态
synchronized 方法占用的锁是当前实例对象锁。
(3)修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。 和 synchronized 方
法一样,synchronized(this)代码块也是锁定当前对象的。synchronized 关键字加到 static 静态方法和
synchronized(class)代码块上都是是给 Class 类上锁。这里再提一下:synchronized关键字加到非 static 静态
方法上是给对象实例上锁。

2.synchronized的底层原理

synchronized 关键字底层原理属于 JVM 层面。通过 JDK 自带的 javap 命令查看 Foo类的相关字节码信息: javap  -v Client$Foo.class

synchronized 同步语句块的实现使用的是 monitorenter 和 monitorexit 指令,其中 monitorenter 指令指向同
步代码块的开始位置,monitorexit 指令则指明同步代码块的结束位置。 当执行 monitorenter 指令时,线程试图
获取锁也就是获取 monitor(monitor对象存在于每个Java对象的对象头中,synchronized 锁便是通过这种方式获取
锁的,也是为什么Java中任意对象可以作为锁的原因) 的持有权.当计数器为0则可以成功获取,获取后将锁计数器设
为1也就是加1。相应的在执行 monitorexit 指令后,将锁计数器设为0,表明锁被释放。如果获取对象锁失败,那当
前线程就要阻塞等待,直到锁被另外一个线程释放为止。

synchronized 修饰方法的的情况

synchronized 修饰的方法并没有 monitorenter 指令和 monitorexit 指令,取得代之的确实是
ACC_SYNCHRONIZED 标识,该标识指明了该方法是一个同步方法,JVM 通过该 ACC_SYNCHRONIZED 访问标志来
辨别一个方法是否声明为同步方法,从而执行相应的同步调用。

原文地址:https://www.cnblogs.com/strongmore/p/11285977.html

时间: 2024-12-16 06:07:14

谈谈java中的synchronized关键字的相关文章

巨人大哥谈Java中的Synchronized关键字用法

巨人大哥谈Java中的Synchronized关键字用法 认识synchronized 对于写多线程程序的人来说,经常碰到的就是并发问题,对于容易出现并发问题的地方价格synchronized基本上就搞定 了,如果说不考虑性能问题的话,这一操绝对能应对百分之九十以上的情况,若对于性能方面有要求的话就需要额外的知识比如读写锁等等.本文目的先了解透彻synchronized的基本原理. Synchronized的基本使用 Synchronized的作用主要有三个: (1)确保线程互斥的访问同步代码 

关于Java中的synchronized关键字

[内容简介] 本文主要介绍Java中如何正确的使用synchronized关键字实现线程的互斥锁. [能力需求] 至少已经完整的掌握了Java的语法基础,基本的面向对象知识,及创建并启动线程. [正文] 关于synchronized关键字的使用,很多说法是“锁同一个对象”就可以确保锁是正常的,今天,有人提了一个问题,我觉得非常不错,所以与各位一起分享一下. 在这里,就不提关于线程和synchronized关键字的基本使用了,以非常传统的“银行取钱”的故事为案例,直接上代码:Ps:以下代码是直接敲

Java中利用synchronized关键字实现多线程同步问题

Java 中多线程的同步依靠的是对象锁机制,synchronized关键字就是利用了封装对象锁来实现对共享资源的互斥访问. 下面以一个简单例子来说明多线程同步问题,我们希望在run()方法里加入synchronized关键字来实现互斥访问. package com.clark.thread; public class MyThread implements Runnable{     private int threadId;          public MyThread(int id){

Java中的Synchronized关键字用法

认识synchronized 对于写多线程程序的人来说,经常碰到的就是并发问题,对于容易出现并发问题的地方加上synchronized修饰符基本上就搞定 了,如果说不考虑性能问题的话,这一招绝对能应对百分之九十以上的情况,若对于性能方面有要求的话就需要额外的知识比如读写锁等等.本文目的先了解透彻synchronized的基本原理. Synchronized的基本使用 Synchronized的作用主要有三个: (1)确保线程互斥的访问同步代码 (2)保证共享变量的修改能够及时可见 (3)有效解决

java中的synchronized关键字

参考:http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html 多线程问题的根因: 多线程环境下,对一个对象更改的时候,一个线程A对某个变量做了改变,但是还没改变完成能,就被另外一个线程B抢去了cpu,那么A就不会再执行了,因此导致了数据不一致行为.针对上面引文中银行取款存款的例子,本来存一百取一百正好抵消,但是由于多线程的之间的肆意抢占,有些取存款的操作没有完成,自然导致结果千奇百怪. 关键点: synchronized

Java中使用同步关键字synchronized需要注意的问题

在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行.synchronized既可以加在一段代码上,也可以加在方法上. 关键是,不要认为给方法或者代码段加上synchronized就万事大吉,看下面一段代码: class Sync { public synchronized void test() { System.out.println("test开始.."); try { Thread.sle

理解java中的volatile关键字

Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了 实现代码线程的安全性.Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分. volatile 写和读的内存语义: 线程 A 写一个 volatile 变量,实质上是线程 A

详细讲解 java 中的synchronized 转自 http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html

Java synchronized详解 第一篇: 使用synchronized 在编写一个类时,如果该类中的代码可能运行于多线程环境下,那么就要考虑同步的问题.在Java中内置了语言级的同步原语 --synchronized,这也大大简化了Java中多线程同步的使用.我们首先编写一个非常简单的多线程的程序,是模拟银行中的多个线程同时对同一 个储蓄账户进行存款.取款操作的.在程序中我们使用了一个简化版本的Account类,代表了一个银行账户的信息.在主程序中我们首先生成了 1000个线程,然后启动

Java并发之synchronized关键字深度解析(一)

前言 近期研读路神之绝世武学,徜徉于浩瀚无垠知识之海洋,偶有攫取吉光片羽,惶恐未领略其精髓即隐入岁月深处,遂急忙记录一二,顺备来日吹cow之谈资.本小系列为并发之亲儿子-独臂狂侠synchronized专场. 一.使用场景 synchronized是java中的一个关键字,用于给对象加锁,保证在单机的并发条件下线程安全.原子性和可见性是它保证线程安全的基础功能.一定要注意它锁的是对象,而且它是一个排他的非公平可重入锁.本文先从使用的场景上来展现其作用. 1.用在普通方法中 常用的格式如下所示: