方法锁、对象锁、类锁的意义和区别

简介: 方法锁、对象锁、类锁的意义和区别

synchronized 是用来处理多个线程访问同一个代码块或者是方法,或者是一个类。


方法锁:


每个类的对象对应一个锁,当对象中的某个方法被synchronized修饰后,调用该方法的时候必须获得该对象的“锁”

。该方法一旦执行就会占有该锁,别的线程使用该对象调用这个方法的时候就会被阻塞直到这个方法执行完后释放锁,被阻塞的线程才能获得锁,从而进入执行状态。

这种机制确保了在同一时刻,对于每一个对象的实例,其所有声明为synchronized方法中最多只有一个处于可执行状态。从而避免了类成员变量的访问冲突。


1,当使用同一个对象调用加了synchronized修饰的方法,如下所示。


public class Demo4 {
  public static void main(String[] args) {
   Demo4 d = new Demo4();
   new Thread(){
    public void run() {
    d.method1();
    };
   }.start();
   new Thread(){
    public void run() {
     d.method2();
    };
   }.start();
  }
  public synchronized void method1(){ 
    System.out.println("method1------开始");
    try {
    Thread.sleep(2000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("method1------结束");
  }
  public synchronized void method2(){ 
  System.out.println("method2------开始");
  try {
    Thread.sleep(2000);
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  System.out.println("method2------结束");
   }
}


结果如下:


method1------开始

method1------结束

method2------开始

method2------结束


由此可得,当使用第一个线程调用method1的时候,method1就会获得当前对象的锁,然后进入方法,在这个时候线程二执行method2方法的时候是进不去的,因为当前对象d的锁已经被method1方法获取到。所以线程二执行method2方法的时候获取不到锁,只能阻塞,然后等待method1方法释放锁后method2才得以执行。


当使用不同的对象调用加了synchronized修饰的方法,如下所示。


ublic class Demo4 {
  public static void main(String[] args) {
  Demo4 d1 = new Demo4();
  Demo4 d2 = new Demo4();
   new Thread(){
    public void run() {
    d1.method1();
    };
   }.start();
   new Thread(){
    public void run() {
     d2.method2();
    };
   }.start();
  }
  public synchronized void method1(){ 
    System.out.println("method1------开始");
    try {
    Thread.sleep(2000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("method1------结束");
  }
  public synchronized void method2(){ 
  System.out.println("method2------开始");
  try {
    Thread.sleep(2000);
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  System.out.println("method2------结束");
   }
}


结果入下:


method1------开始

method2------开始

method2------结束

method1------结束


有结果可以得出:使用不同的对象调用这两个方法,可以看到这两个方法是同时执行的。因为调用方法的对象不同,所以两个方法获取到的锁也不同,结果就是这两个方法分别获取了这两个对象的锁。然后两个方法会同时执行。


对象锁:

当一个对象中有synchronized方法或者sychronized代码块的时候。调用此对象方法的时就必须获取对象锁,如果此对象的锁已被别的线程获取,那么就必须等待别的线程释放锁后才可以 执行该方法(方法锁也是对象锁)。


方法锁和对象锁都差不多,方法锁针对的是一个方法。对象锁则是一个代码块,针对的是一部分代码。


对象锁和方法锁的两种形式。


1,方法锁:


public synchronized void method1(){ 
    System.out.println("method1------开始");
    try {
    Thread.sleep(2000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("method1------结束");
  }


2,代码块:


public  void method2(){ 
  synchronized(this){
    System.out.println("method2------开始");
    try {
    Thread.sleep(2000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("method2------结束");
  }
   }


类锁:

synchronized修饰的代码块或者synchronized修饰的静态方法。


由于一个类不论被实例化多少次,这个类中的静态方法和变量只会被加载和初始化一份,一旦某个静态方法被修饰为synchronized,此类的所有实例化对象共用一把锁,称之为类锁。


类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的


如下两种形式:


静态synchronized:

public static synchronized void method1(){  
    System.out.println("method1------开始");
    try {
    Thread.sleep(2000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("method1------结束");
  }


代码块类锁:

public  void method2(){ 
  synchronized(Demo4.this){
    System.out.println("method2------开始");
    try {
    Thread.sleep(2000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("method2------结束");
  }
   }


如有错误,还请指出,谢谢!


相关文章
|
4月前
|
存储 监控
多线程之AQS独占锁
多线程之AQS独占锁
23 0
|
30天前
|
Java
锁对象
锁对象
48 1
|
3月前
|
Java
Java多线程同步锁、Lock锁和等待唤醒机制及代码演示
Java多线程同步锁、Lock锁和等待唤醒机制及代码演示
|
8月前
|
Java
Java 中线程同步机制synchronized,互斥锁,死锁,释放锁的详解
Java 中线程同步机制synchronized,互斥锁,死锁,释放锁的详解
62 0
|
9月前
|
安全 Java
synchronized 锁与 ReentrantLock 锁的区别
synchronized 锁与 ReentrantLock 锁的区别
89 0
|
安全 Java 对象存储
浅谈synchronized锁原理
保证线程安全的一个重要手段就是通过加锁的形式实现,今天盘点一下Java中锁的八股文
129 0
【JavaSE】多线程篇(四)线程的同步机制、互斥锁、线程死锁与释放锁
文章目录 1 走进Synchronized 1.1 线程同步机制 1.2 同步的具体方法--synchronized 1.3 使用线程同步解决售票问题 2 互斥锁 2.1 基本介绍 2.2 使用互斥锁解决售票问题 3 线程死锁 3.1 基本介绍 3.2 案例演示 4 释放锁 4.1 释放锁的情况 4.2 不会释放锁的情况
【JavaSE】多线程篇(四)线程的同步机制、互斥锁、线程死锁与释放锁
|
安全 Java
同步代码块、同步方法解决数据安全问题、线程安全的类及Lock锁
同步代码块、同步方法解决数据安全问题、线程安全的类及Lock锁的简单示例
87 1
同步代码块、同步方法解决数据安全问题、线程安全的类及Lock锁
|
设计模式 安全 算法
Java多线程(二)、线程的生命周期、线程的同步、Synchronized的使用方法、同步代码块、同步方法、同步机制中的锁、同步的范围、Lock(锁、不会释放锁的操作、单例设计模式之懒汉式(线程安全)
Java多线程(二)、线程的生命周期、线程的同步、Synchronized的使用方法、同步代码块、同步方法、同步机制中的锁、同步的范围、Lock(锁、不会释放锁的操作、单例设计模式之懒汉式(线程安全)
Java多线程(二)、线程的生命周期、线程的同步、Synchronized的使用方法、同步代码块、同步方法、同步机制中的锁、同步的范围、Lock(锁、不会释放锁的操作、单例设计模式之懒汉式(线程安全)
|
安全 Java 调度
【学习笔记】线程原子性-锁 synchronized的用法(1)
【学习笔记】线程原子性-锁 synchronized的用法
108 0