synchronized 的使用方法

2020-02-13  本文已影响0人  blank_white

https://www.cnblogs.com/xyabk/p/10901291.html

synchronized的用法可以这么理解
在执行到被synchronized划定范围的代码时,会去查看一个标识
①如果这个标识没有被上锁,将这个标识锁上,待执行完毕后解锁
②如果这个标识被上锁了,则等待解锁

synchronized 的三种应用方式(以什么作为了标识)

实际上,每个对象都有一个内部锁,使用 synchronized 关键字使用的就是这个内部锁。

1.修饰代码块

//括号内的参数应该是一个具体对象
synchronized(Object object){

}
例:
class  Timer{
    private static int num=0;
    public  void funSyn1() {
        int i;
        xxxxx;
 
        synchronized (this) {
        //synchronized (object) {
          num++;
        }

        xxxxx;
        xxxxx;
    }

    public  void funSyn2() {
        int i;
        xxxxx;
 
        synchronized (this) {
        //synchronized (object) {
          num++;
        }

        xxxxx;
        xxxxx;
    }

       public  void funSyn3() {
        int i;
        xxxxx;
          num++;
    
        xxxxx;
        xxxxx;
    }
}

在执行 synchronized 包围的代码块时,会检查 括号内的 参数对象是否被上锁(也就是将括号内的对象作为标识)
如果括号内是 this 关键字,则检查 调用此方法的类的实例 是否被上锁(也就是将调用该方法的这个此类的实例作为标识)

Timer t1,t2;
不同线程执行 t1.funSyn1 与 t1.funSyn1 与 t1.funSyn2 中synchronized修饰块内代码的时候,会同步(因为它们执行的时候都会先去 检查  t1 有没有锁住)
不同线程执行 t1.funSyn1 与 t2.funSyn1 与 t1.funSyn3 中synchronized修饰块内代码的时候,不会用不(它们执行的时候分别是 检查  t1 与 检查 t2  与 不检查直接执行)

2.修饰类的方法

Class A{
  public synchronized void fun(){
    xxx;
    xxx;
  }
}

等效
Class A{
  public  void fun(){
    synchronized(this){
      xxx;
      xxx;
    }

  }
}

在修饰类的方法时,相当于将this作为参数,将整个方法作为代码块,与 上种情况类似

  1. 修饰静态方法
Class T{
  public synchronized static funSyn1(){
  }
  public synchronized  funSyn2(){
  }
}

修饰静态方法时,调用该静态方法时,会先检查该类是否上锁(可以理解为 将 类T 作为 标识)(实际上是对 T.class 这个对象的内部锁上锁)

T t1;
不同线程执行 T.funSyn1  与  T.funSyn1 与 t1.funSyn1 时,会同步(因为执行的时候会先检查 类T 与 类T 与 类T 是否上锁)
不同线程执行 t1.funSyn1 与 t1.funSyn2 时,不会同步(因为执行的时候会先检查类T 与 实例 t1 是否上锁)
上一篇 下一篇

猜你喜欢

热点阅读