synchronized你真的会用吗?

56 阅读2分钟

阻塞式的解决方案:synchronized,来解决上述问题,即俗称的【对象锁】,它采用互斥的方式让同一时刻至多只有一个线程能持有【对象锁】,其它线程再想获取这个【对象锁】时就会阻塞住。这样就能保证拥有锁的线程可以安全的执行临界区内的代码,不用担心线程上下文切换

下面的每个示例分别打印什么值?

case1:

import lombok.extern.slf4j.Slf4j;

@Slf4j
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();
}

case2:

import lombok.extern.slf4j.Slf4j;

@Slf4j
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();
}

case3:

import lombok.extern.slf4j.Slf4j;

@Slf4j
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();
}

case4:

import lombok.extern.slf4j.Slf4j;

@Slf4j
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();
}

case5:

import lombok.extern.slf4j.Slf4j;

@Slf4j
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();
    new Thread(() -> {
        n1.a();
    }).start();
    new Thread(() -> {
        n1.b();
    }).start();
}

case6:

import lombok.extern.slf4j.Slf4j;

@Slf4j
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();
}

case7:

import lombok.extern.slf4j.Slf4j;

@Slf4j
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();
}

case8:

import lombok.extern.slf4j.Slf4j;

@Slf4j
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();
}