zoukankan      html  css  js  c++  java
  • Java 中对象锁和类锁的区别?

    一  对象锁和类锁的关系 

    /*
     * 
     对象锁和【类锁】 全局锁的关系?
            对象锁是用于对象实例方法,或者一个对象实例上的   this
            类锁是用于类的静态方法或者一个类的class对象上的。 Ag.class
            
            我们知道,类的对象实例可以有很多个,但是每个类只有一个class对象,
            所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。
     */

    对象锁,  不同对象。

    public class SynchrDemo {
        public static void main(String[] args) {
            
            Thread1 thread1 = new Thread1();
            Thread1 thread2 = new Thread1();
            
            thread1.start();
            thread2.start();
    
        }
    }
    
    class Ag{
        public void show(){
            // this 是当前对象的实例,由于新建两个对象,不是同一对象。所以这里是锁不住的。   代码快的方式,比修饰在方法上更细化控制。
            synchronized (this) {
                for (int i = 0; i < 4; i++) {
                    System.out.println(Thread.currentThread().getName() + " i=" + i);
                }
            }
        }
    
    }
    
    class Thread1 extends Thread{    
        @Override
        public void run() {
            //这里是新建对象  主方法中new了两个thread,就是new了两个Ag对象
            Ag ag = new Ag();
            ag.show();
            
        }    
    }

    关键字修饰方法

    public class SynchrDemo {
        public static void main(String[] args) {
            
            Thread1 thread1 = new Thread1();
            Thread1 thread2 = new Thread1();
            
            thread1.start();
            thread2.start();
    
        }
    }
    
    class Ag{
        // 这次修饰的是方法,范围比代码块要大,意味着在这个区域内,锁生效的时候,都是在阻塞,其他线程的等待时间就会增加。
        // 这次实验的非同一对象,所以这里的锁是不起作用的。
        public synchronized void show(){
                for (int i = 0; i < 4; i++) {
                    System.out.println(Thread.currentThread().getName() + " i=" + i);
                }
        }
    
    }
    
    class Thread1 extends Thread{    
        @Override
        public void run() {
            //这里是新建对象  主方法中new了两个thread,就是new了两个Ag对象
            Ag ag = new Ag();
            ag.show();
            
        }    
    }

    二  对象锁  同一对象

    package com.aaa.threaddemo;
    /*
     * 一 Java中的关键字  synchronized  是啥?
     *         synchronized是Java提供的一个并发控制的关键字。
     * 
     *         用法:同步方法 和 同步代码块。
     *              可以修饰方法 也可以  修饰代码块。
     *         
     *         作用: 被synchronized修饰的代码块及方法,在同一时间,只能被单个线程访问。【保证线程安全】
    
        1 修饰方法和代码块有什么不同?
             二者的结果是一样的
             
             修饰方法时,作用域是整个方法,控制的范围大。
         
             synchronized 代码块 可控制具体的作用域,更精准控制提高效率。
             减少阻塞带来的时间问题。
    
        2 同步锁的给谁用的?
            同步锁基于对象,只要锁的来源一致,即可达到同步的作用。
            所以,但对象不一样,则不能达到同步效果。
    
        3 synchronized修饰方法,代码块,锁未释放,此时,其他线程调用同一对象的其他被synchronized修饰的方法,代码块,会如何?
            当线程 A 调用某对象的synchronized 方法 或者 synchronized 代码块时,若同步锁未释放,
            其他线程调用同一对象的其他 synchronized 方法 或者 synchronized 代码块时将被阻塞,直至线程 A 释放该对象的同步锁。(注意:重点是其他)
    
        4 调用非synchronized方法 ,代码快呢?
            当线程 A 调用某对象的synchronized 方法 或者 synchronized 代码块时,无论同步锁是否释放,
            其他线程调用同一对象的其他 非 synchronized 方法 或者 非 synchronized 代码块时可立即调用。
    
        5 全局锁如何实现?
            全局锁: 锁住整个 Class,而非某个对象或实例。1-4都是实例锁
            实现: 静态 synchronized 方法
            
            static 声明的方法为全局方法,与对象实例化无关,
            所以 static synchronized 方法为全局同步方法,与对象实例化无关。
    
        6 synchronized 具体 Class 的代码块?
            synchronized (Ag.class) 获得的同步锁是全局的,
            static synchronized 获得的同步锁也是全局的,同一个锁,所以达到同步效果。
    
        7 对象锁和【类锁】 全局锁的关系?
            对象锁是用于对象实例方法,或者一个对象实例上的   this
            类锁是用于类的静态方法或者一个类的class对象上的。 Ag.class
            
            我们知道,类的对象实例可以有很多个,但是每个类只有一个class对象,
            所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。
    
    
    
    
     * 
     * 
     */
    
    /*
     * 
     对象锁和【类锁】 全局锁的关系?
            对象锁是用于对象实例方法,或者一个对象实例上的   this
            类锁是用于类的静态方法或者一个类的class对象上的。 Ag.class
            
            我们知道,类的对象实例可以有很多个,但是每个类只有一个class对象,
            所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。
     */
    
    
    public class SynchrDemo {
        public static void main(String[] args) {
            
            // 改造后,可以确保是同一对象  验证  synchronized  是否生效
            Ag ag = new Ag();
            
            Thread1 thread1 = new Thread1(ag);
            Thread1 thread2 = new Thread1(ag);
            
            thread1.start();
            thread2.start();
    
        }
    }
    
    class Ag{
        // 这次修饰的是方法,范围比代码块要大,意味着在这个区域内,锁生效的时候,都是在阻塞,其他线程的等待时间就会增加。
        // 这次实验的同一对象,所以这里的锁是起作用的。
        public synchronized void show(){
                for (int i = 0; i < 4; i++) {
                    System.out.println(Thread.currentThread().getName() + " i=" + i);
                }
        }
    
    }
    
    /*
     *   改造一些 对象的生成,确保在Thread1 中获得的是同一对象
     */
    class Thread1 extends Thread{    
        
        private Ag mag;
        
        public  Thread1(Ag ag) {
            mag = ag;
        }
        
        @Override
        public void run() {
            mag.show();
            
        }    
    }

    验证代码快的方式?

    public class SynchrDemo {
        public static void main(String[] args) {
            
            // 改造后,可以确保是同一对象  验证  synchronized  是否生效
            Ag ag = new Ag();
            
            Thread1 thread1 = new Thread1(ag);
            Thread1 thread2 = new Thread1(ag);
            
            thread1.start();
            thread2.start();
    
        }
    }
    
    class Ag{
        // 这次修饰的是方法,范围比代码块要大,意味着在这个区域内,锁生效的时候,都是在阻塞,其他线程的等待时间就会增加。
        // 这次实验的同一对象,所以这里的锁是起作用的。
        public  void show(){
            synchronized (this) {
                for (int i = 0; i < 4; i++) {
                    System.out.println(Thread.currentThread().getName() + " i=" + i);
                }
                
                // this 就是当前的对象,我们现在获得就是同一对象
                System.out.println(this);
            }
        }
    
    }
    
    /*
     *   改造一些 对象的生成,确保在Thread1 中获得的是同一对象
     */
    class Thread1 extends Thread{    
        
        private Ag mag;
        
        public  Thread1(Ag ag) {
            mag = ag;
        }
        
        @Override
        public void run() {
            mag.show();
            
        }    
    }

    三   类锁?  非同一对象

    /*
     * 
     * 类锁,全局锁如何实现?
            全局锁: 锁住整个 Class,而非某个对象或实例
            
            实现:   
            1    在静态方法上用 synchronized 关键字修饰
            2    在代码块上使用 类名.class
                
            
            static 声明的方法为全局方法,与对象实例化无关,
            所以 static synchronized 方法为全局同步方法,与对象实例化无关。
     */
    
    public class SynchrDemo {
        public static void main(String[] args) {
            
            //非同一对象
            Thread2 thread1 = new Thread2();
            Thread2 thread2 = new Thread2();
            
            thread1.start();
            thread2.start();
    
        }
    }
    
    class Ag{
        public  void show(){
            // 使用 synchronized()  方法,将锁控制在代码快上。
            synchronized (Ag.class) {
                for (int i = 0; i < 4; i++) {
                    System.out.println(Thread.currentThread().getName() + " i=" + i);
                }
                
                // this 就是当前的对象,我们现在获得就是非同一对象
                System.out.println(this);
            }
        }
    
    }
    
    class Thread2 extends Thread{
        
        @Override
        public void run() {
            Ag ag = new Ag();
            ag.show();
            
        }    
    }

    测试   关键字修饰 static 方法  

    public class SynchrDemo {
        public static void main(String[] args) {
            
            //非同一对象
            Thread2 thread1 = new Thread2();
            Thread2 thread2 = new Thread2();
            
            thread1.start();
            thread2.start();
    
        }
    }
    
    class Ag{
        // 静态的方法  被synchronized 修饰后, 锁住的是 类。
        public static synchronized  void show(){
                for (int i = 0; i < 4; i++) {
                    System.out.println(Thread.currentThread().getName() + " i=" + i);
                }            
        }
    
    }
    
    class Thread2 extends Thread{
        
        @Override
        public void run() {
            Ag ag = new Ag();
            ag.show();
            
        }    
    }

  • 相关阅读:
    JavaScript 闭包+封装+异步同步区别
    CSS基础(三)盒子模型
    CSS基础(二)浮动
    CSS基础(一)
    HTML基础(二)
    JAVA 微信开发
    MAVEN学习总结1
    Java开发中的23种设计模式详解(转)
    navicat for mysql 10.1.7注册码
    jQuery.Validate验证库
  • 原文地址:https://www.cnblogs.com/ZXF6/p/14102874.html
Copyright © 2011-2022 走看看