线程八锁问题--synchronize所在哪个对象?

synchronized 加在成员方法上,锁的是this 对象,对于调用者来说,锁的是同一个对象、谁先拿到锁谁先执行。

synchronized加载静态方法上,所的是类对象。静态方法类加载的时候就有了。同多个对象通用一把锁。

1、情况1

@Slf4j(topic = "c.Number")
/**
 * synchronized:锁的是方法的调用者,
 * 下面两个方法用的是同一把锁,谁先拿到锁谁先执行。
 * synchronized 记在成员方法上,锁的是this 对象,对于调用者来说,锁的是同一个对象
 */
class Number{
 public synchronized void a() {
 log.debug("1");
 }
 public synchronized void b() {
 log.debug("2");
 }
}
public static void main(String[] args) {
 Number n1 = new Number();
 new Thread(()->{ n1.a(); }).start();
 new Thread(()->{ n1.b(); }).start();
    //结果:12或者21
}

 2、情况2

@Slf4j(topic = "c.Number")
/**
 * synchronized:锁的是方法的调用者,
 * 下面两个方法用的是同一把锁,谁先拿到锁谁先执行。
 * synchronized 记在成员方法上,锁的是this 对象,对于调用者来说,锁的是同一个对象
 */
class Number{
 public synchronized void a() {
 sleep(1);
 log.debug("1");
 }
 public synchronized void b() {
 log.debug("2");
 }
}
public static void main(String[] args) {
 Number n1 = new Number();
 new Thread(()->{ n1.a(); }).start();
 new Thread(()->{ n1.b(); }).start();
    //1s后12,或 2 1s后 1
}

  3、情况3

@Slf4j(topic = "c.Number")
class Number{
 public synchronized void a() {
 sleep(1);
 log.debug("1");
 }
 public synchronized void b() {
 log.debug("2");
 }
  //没有锁,不是同步方法,不受锁的影响
 public void c() {
 log.debug("3");
 }
}
public static void main(String[] args) {
 Number n1 = new Number();
 new Thread(()->{ n1.a(); }).start();
 new Thread(()->{ n1.b(); }).start();
 new Thread(()->{ n1.c(); }).start();
    //可能的结果:
    //3 1s后 12  ---第一个线程先进来获得锁。c方法不用争抢锁资源,直接执行
    //32 1s后 1  ---第二个线程先进来获得锁,2和3的顺序无法保证。
    //23 1s后 1  ---同上
    //
}

4、情况4

@Slf4j(topic = "c.Number")
class Number{
 public synchronized void a() {
 sleep(1);
 log.debug("1");
 }
 public synchronized void b() {
 log.debug("2");
 }
}
public static void main(String[] args) {
     //两个对象,两个调用者 两个锁  互不干扰
 Number n1 = new Number();
 Number n2 = new Number();
 new Thread(()->{ n1.a(); }).start();
 new Thread(()->{ n2.b(); }).start();
    // 2 1s后 1

}

5、情况5

@Slf4j(topic = "c.Number")
class Number{
    //synchronized在和静态方法上,锁的是类对象
     public static synchronized void a() {
     sleep(1);
     log.debug("1");
     }
    //synchronized 在普通方法上 锁的是this对象
     public synchronized void b() {
     log.debug("2");
     }
}
public static void main(String[] args) {
     Number n1 = new Number();
     new Thread(()->{ n1.a(); }).start();
     new Thread(()->{ n1.b(); }).start();
    //2 1s后 1
    // 因为两个的锁对象不同
}

6、情况6  

@Slf4j(topic = "c.Number")
/**
 * 两个方法都是static,类加载的时候就存在了。
 * 调用的时候Number全局唯一,锁的是class
 * 加了static 就和调用对象是几个没关系(同一把锁)。
 */
class Number{
 public static synchronized void a() {
 sleep(1);
 log.debug("1");
 }
 public static synchronized void b() {
 log.debug("2");
 }
}
public static void main(String[] args) {
 Number n1 = new Number();
 new Thread(()->{ n1.a(); }).start();
 new Thread(()->{ n1.b(); }).start();
    //:1s 后12, 或 2 1s后 1
}

7、情况7

@Slf4j(topic = "c.Number")
/**
* 两个方法两把锁,不互干扰
*/
class Number{
 public static synchronized void a() {
 sleep(1);
 log.debug("1");
 }
 public synchronized void b() {
 log.debug("2");
 }
}
public static void main(String[] args) {
 Number n1 = new Number();
 Number n2 = new Number();
 new Thread(()->{ n1.a(); }).start();
 new Thread(()->{ n2.b(); }).start();
    //:2 1s 后 1
    //两个锁,互不干扰
}

8、情况8

@Slf4j(topic = "c.Number")
/**
* synchronized 都在静态方法上,锁对象是一个
*/
class Number{
 public static synchronized void a() {
 sleep(1);
 log.debug("1");
 }
 public static synchronized void b() {
 log.debug("2");
 }
}
public static void main(String[] args) {
 Number n1 = new Number();
 Number n2 = new Number();
 new Thread(()->{ n1.a(); }).start();
 new Thread(()->{ n2.b(); }).start();
    //:1s 后12, 或 2 1s后 1
    //同一把锁。互斥
}

 

posted @ 2022-09-27 21:43  iyandongsheng  阅读(59)  评论(0编辑  收藏  举报