zoukankan      html  css  js  c++  java
  • 聊聊synchronized的锁问题

    本文不会特别深入细致地讨论synchronized,只是做一个通俗易懂的说明,以及看清一类问题的本质,希望能给大家一点启发。

    问题描述

    有一个类A,提供了三个方法。分别是静态同步方法,非静态同步方法,含有静态代码块的方法

     1 class A{
     2     public static synchronized void print1(){
     3         print();
     4     }
     5     public synchronized void print2(){
     6         print();
     7     }
     8     public void print3(){
     9         synchronized (new Object()){
    10             print();
    11         }
    12     }
    13     private static void print(){
    14         while(true){
    15             String threadName = Thread.currentThread().getName();
    16             System.out.println(threadName);
    17         }
    18     }
    19 }

    请回答一下四种情况的输出结果

     1 class Test {
     2     // 1.两个线程,同一个类,调用静态同步方法print1
     3     @Test
     4     public void test1() {
     5         Thread thread1 = new Thread(() -> A.print1());
     6         Thread thread2 = new Thread(() -> A.print1());
     7         thread1.start();
     8         thread2.start();
     9     }
    10     // 2.两个线程,同一个对象,调用非静态同步方法print2
    11     @Test
    12     public void test2() {
    13         A a = new A();
    14         Thread thread1 = new Thread(() -> a.print2());
    15         Thread thread2 = new Thread(() -> a.print2());
    16         thread1.start();
    17         thread2.start();
    18     }
    19     // 3.两个线程,不同对象,调用非静态同步方法print2
    20     @Test
    21     public void test3() {
    22         Thread thread1 = new Thread(() -> new A().print2());
    23         Thread thread2 = new Thread(() -> new A().print2());
    24         thread1.start();
    25         thread2.start();
    26     }
    27     // 4.两个线程,同一个对象,调用普通非静态方法(带有同步代码块)print3
    28     @Test
    29     public void test4() {
    30         A a = new A();
    31         Thread thread1 = new Thread(() -> a.print3());
    32         Thread thread2 = new Thread(() -> a.print3());
    33         thread1.start();
    34         thread2.start();
    35     }
    36 }

    问题答案

    先直接报上答案:

    1. 一直输出“Thread-1”
    2. 一直输出“Thread-1”
    3. 交替输出“Thread-1”和“Thread-2”
    4. 交替输出“Thread-1”和“Thread-2”

    问题本质分析

    不废话,直接点出,这四个问题只要明白两件事即可:

    • 一个线程是否能执行被同步了的方法,主要看是否能拿到锁对象
    • 静态方法的同步锁是类对象本身,非静态方法的同步锁是实例对象本身,同步代码块的同步锁是括号中传入的对象

    所以

    • 如果两个线程执行方法用到了同一个锁对象,则一个线程执行时,另一个线程必须等待其释放锁才能拿到锁,所以此时两个线程会互斥

    所以

    • 1中两个线程执行方法的锁对象都是类对象A,所以线程之间互斥
    • 2中两个线程执行方法的锁对象都是实例对象a,所以线程之间互斥
    • 3中两个线程执行方法的锁对象分别是new出来的两个实例对象a,所以线程互不影响
    • 4中两个线程执行方法的锁对象分别是new出来的两个实例对象object,所以线程互不影响

    Game Over

    公众号 - 低并发编程

  • 相关阅读:
    算法
    nginx配置https
    IE中JS跳转丢失referer的问题
    js 调用字符串类型的 js语句
    移动端iOS中input聚焦不灵敏
    上传图片转换格式为base64并预览
    转:手机号脱敏
    转:Lodash之throttle(节流)与debounce(防抖)总结
    转:tinyMCE中图片的自定义上传
    chrome input 输入框去掉黄色
  • 原文地址:https://www.cnblogs.com/flashsun/p/7270139.html
Copyright © 2011-2022 走看看