• 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方法也相当于全局锁,相当于锁住了该整个方法的代码段

  • 相关阅读:
    hdu 4293 2012成都赛区网络赛 dp ****
    hdu 4291 2012成都赛区网络赛 矩阵快速幂 ***
    hdu 4288 线段树 暴力 **
    hdu 4278 2012天津赛区网络赛 数学 *
    zoj 3888 线段树 ***
    虚拟化技术详解
    BRD、MRD 和 PRD 之间的区别与联系有哪些?
    salt-master配置、salt-minion配置
    Shell 脚本实现 Linux 系统监控
    Centos 7 安装 Xen
  • 原文地址:https://www.cnblogs.com/liuqing576598117/p/9958350.html
Copyright © 2020-2023  润新知