《Java源码分析》:Java中synchronized关键字的使用

 作者简介:大家好,我是码炫码哥,前中兴通讯、美团架构师,现任某互联网公司CTO,兼职码炫课堂主讲源码系列专题


代表作:《jdk源码&多线程&高并发》,《深入tomcat源码解析》,《深入netty源码解析》,《深入dubbo源码解析》,《深入springboot源码解析》,《深入spring源码解析》,《深入redis源码解析》等


联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬。码炫课堂的个人空间-码炫码哥个人主页-面试,源码等

对于关键字synchronized,研究起来,发现还是有许多让自己模糊的地方,网上也有很多篇博客对synchronized关键字的使用讲解的相当好,自己也受益匪浅。自己之所以还写一篇博客来介绍synchronized的目的只有一个:加深自己对synchronized的理解。

写博客有时候确实是一个好的东西,往往研究某个知识点的时候,自己觉得弄懂了,但是过几天查不多就忘了模糊了,而写博客可以增加对知识点的理解和加深知识的记忆。

synchronized关键字是解决多线程并发同步的方法之一。

synchronized可以修饰如下几个方面。

1、修饰一个代码块,作用的对象是调用这个代码块的对象

2、修饰一个方法,作用的对象是调用这个方法的对象

3、修饰一个静态方法,作用的对象是静态方法所属的类的所有对象

4、修饰一个类,作用的对象是该类的所用对象。

下面一一进行介绍

1、synchronized修饰一个代码块

1.1 一个线程访问一个对象obj中的synchronize(this)同步代码块时,其它线程试图访问该对象obj的synchronize(this)同步块时将会被阻塞。

看下面这个例子

Demo1

        class MyThread implements Runnable{
            private static final int NUM = 3;
            @Override
            public void run() {
                synchronized(this){
                    for(int i =0;i<NUM;i++){
                        System.out.println(Thread.currentThread().getName()+"  running .....");
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
    
                }
            }
    
        }

测试代码如下:

        public class SyncCodeBlock {
    
            public static void main(String[] args) {
                MyThread mt = new MyThread();
                new Thread(mt,"Thread1").start();
                new Thread(mt,"Thread2").start();
            }
    
        }

运行结果:

    Thread2  running .....
    Thread2  running .....
    Thread2  running .....
    Thread1  running .....
    Thread1  running .....
    Thread1  running .....

这里,名字为Thread1、Thread2的两个线程都想访问对象mt的同步块synchronized(this),由于只有一个锁,谁拿到的这个锁就该谁访问,也就是说,在任一时刻只能有一个线程访问这一同步代码块。例如,当Thread1线程拿到锁正在执行run里面的代码时,名字为Thread2的线程也想访问同一对象mt的同步块synchroized(this)的同步块将会被阻塞,只有等Thread1访问结束之后释放该对象锁Thread2拿到该对象锁才能访问。

如果我们将测试代码该为如下:

        public static void main(String[] args){
            MyThread mt = new MyThread();
            MyThread mt2 = new MyThread();
            new Thread(mt,"Thread1").start();
            new Thread(mt2,"Thread2").start();
        }

结果如下:

    Thread2  running .....
    Thread1  running .....
    Thread2  running .....
    Thread1  running .....
    Thread2  running .....
    Thread1  running .....

这里,和上面的第一种

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值