Synchronized关键词使用场景解析

synchronized 使用场景

  1. synchronized包裹代码块:
    I . synchronized(对象){}
    II . synchronized(类名.class){}
    III. synchronized(this){}
  2. synchronized修饰方法:
    I .public synchronized void memberMethod(){};
    II.public static synchronized void staticMethod(){};

相关赘述

内置锁:每个java对象都可以用做一个实现同步的锁,这些锁成为内置锁。线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁。获得内置锁的唯一途径就是进入这个锁的保护的同步代码块或方法。– 查看出处

对象锁:假设类对象instance的某段代码块被synchronized(obj){}包裹,线程访问该段代码块时便会拿到obj对象的内置锁。在obj对象的内置锁释放前,其他线程仍然可以访问instance对象非同步的方法和代码块(现象一),但是:
  1. 不能进入任何也以obj为锁的代码块;(现象二)
  2. 当obj与instance是同一个对象时,也不能进入任何instance对象的同步方法(现象三)
  由此可见,第一个线程拿到obj对象的内置锁其实就相当于给instance这个对象加上了一个用于同步的独占排他锁(可重入),我们称obj对象为对象锁。– 查看详情

类锁:是相对于对象锁而抽象出来的一种独占排他锁。当线程拿到一个类A的类锁时,其他线程无法访问以类A为锁(A.class)的同步代码块,也无法进入类A的所有静态同步方法。– 查看详情


结论

  无论修饰的是代码块还是方法,只要指定的锁相同就一定会引起多线程的竞争和部分线程阻塞!


判断的关键便是从形式多变的synchronized关键词中挖掘出锁。
现在假设有类A,另有Object类对象obj。得下表:

synchronized形式(均写在在类A中)锁类型
synchronized(obj){}obj对象锁
synchronized(A.class){}A.class类锁
synchronized(this){}当前类对象对象锁
synchronized void memberMethod(){}当前类对象对象锁
static synchronized void staticMethod(){}当前类类锁

场景分析

场景一:synchronized包裹代码块
场景二:synchronized修饰成员方法


其他(待补充)

1.两种场景的区别
2.使用synchronized关键字的缺陷
3.如有问题或错误,请评论告知


SynchronizedVerify类代码

public class SynchronizedVerify {

    /**-------------------------------------包裹代码块------------------------------**/
    Object objA = new Object();
    Object objB = new Object();

    public void blockNormal(){ track("blockNormal");}
    public void blockStyle(){
        synchronized (objA) { track("blockStyle"); }
    }
    /**相同场景下对比**/
    public void blockContrast( ){
        synchronized (objA) { track("blockContrast");}
    }
    public void blockDiffObj(){
        synchronized (objB) { track("blockDiffObj");}
    }
    public void blockOneself(){
        synchronized (this) { track("blockOneself");}
    }

    public void blockClass(){
        synchronized (SynchronizedVerify.class) { track("blockClass");}
    }

    /**-------------------------------------修饰方法------------------------------**/
    public void methodNormal(){ track("methodNormal");}
    public synchronized void methodStyle(){ track("methodStyle");}
    public synchronized void methodContrast(){ track("methodContrast");}/**相同场景下对比**/

    public static void methodStaticNormal(){ track("methodStaticNormal");}
    public synchronized static void methodStatic(){ track("methodStatic");}
    public synchronized static void methodStaticContrast(){ track("methodStaticContrast");}


    /**循环输出一段内容**/
    private static void track(String callerName){
        for(int i = 0;i < 3 ;i++){
            System.out.println(
                    callerName+":"+i+"\t|"+
                    Thread.currentThread().getName());

            Thread.yield();
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值