zoukankan      html  css  js  c++  java
  • synchronized锁住的是代码还是对象,以及synchronized底层实现原理

    synchronized (this)原理:涉及两条指令:monitorenter,monitorexit;再说同步方法,从同步方法反编译的结果来看,方法的同步并没有通过指令monitorenter和monitorexit来实现,相对于普通方法,其常量池中多了ACC_SYNCHRONIZED标示符。

    JVM就是根据该标示符来实现方法的同步的:当方法被调用时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,执行线程将先获取monitor,获取成功之后才能执行方法体,方法执行完后再释放monitor。在方法执行期间,其他任何线程都无法再获得同一个monitor对象。

    synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行。synchronized既可以加在一段代码上,也可以加在方法上。

    class Sync {    
        public synchronized void test() {  
            System.out.println("test开始..");  
            try {  
                Thread.sleep(1000);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
            System.out.println("test结束..");  
        }  
    }  
      
    class MyThread extends Thread {  
        public void run() {  
            Sync sync = new Sync();  
            sync.test();  
        }  
    }  
      
    public class Main {  
        public static void main(String[] args) {  
            for (int i = 0; i < 3; i++) {  
                Thread thread = new MyThread();  
                thread.start();  
            }  
        }  
    }  

    运行结果: test开始.. test开始.. test开始.. test结束.. test结束.. test结束..

    上面的程序起了三个线程,同时运行Sync类中的test()方法,虽然test()方法加上了synchronized,但是还是同时运行起来,貌似synchronized没起作用。 

    注意:synchronized()锁住的是括号里的对象,而不是代码。对于非static的synchronized方法,锁的就是对象本身也就是this。

    则可以这样:

    class Sync {  
      
        public void test() {  
            synchronized (Sync.class) {  
                System.out.println("test开始..");  
                try {  
                    Thread.sleep(1000);  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
                System.out.println("test结束..");  
            }  
        }  
    }  
      
    class MyThread extends Thread {  
      
        public void run() {  
            Sync sync = new Sync();  
            sync.test();  
        }  
    }  
      
    public class Main {  
      
        public static void main(String[] args) {  
            for (int i = 0; i < 3; i++) {  
                Thread thread = new MyThread();  
                thread.start();  
            }  
        }  
    }  

    运行结果: test开始.. test结束.. test开始.. test结束.. test开始.. test结束..

    上面代码用synchronized(Sync.class)实现了全局锁的效果。

    static synchronized方法,static方法可以直接类名加方法名调用,方法中无法使用this,所以它锁的不是this,而是类的Class对象,所以,static synchronized方法也相当于全局锁,相当于锁住了该整个方法的代码段

  • 相关阅读:
    14-ESP8266 SDK开发基础入门篇--上位机串口控制 Wi-Fi输出PWM的占空比,调节LED亮度,8266程序编写
    Zookeeper之Curator(1)客户端基本的创建,删除,更新,查找操作api
    【1】基于quartz框架和Zookeeper实现集群化定时任务系统
    Spring源码学习之:ClassLoader学习(5)-自测
    java多线程:线程体往外抛出异常的处理机制实践
    MySQL详解--锁,事务
    ubuntu下访问支付宝官网,安装安全控件
    spring源码学习之:springAOP实现底层原理
    spring源码学习之:项目公共配置项解决方案
    java多线程:synchronized和lock比较浅析
  • 原文地址:https://www.cnblogs.com/liuqing576598117/p/9958350.html
Copyright © 2011-2022 走看看