synchronized的线程八锁问题

方法上的 synchronized

与使用synchronized(X)等效

class Test{
    
    
    public synchronized void test() {
    
    

    }
}
等价于
class Test{
    
    
    public void test() {
    
    
        synchronized(this) {
    
    

        }
    }
}
class Test{
    
    
    public synchronized static void test() {
    
    
        
    }
}
等价于
class Test{
    
    
    public static void test() {
    
    
        synchronized(Test.class) {
    
    

        }
    }
}

不加 synchronized 的方法

不加 synchronzied 的方法就好比不遵守规则的人,不去老实排队(好比翻窗户进去的)

“线程八锁”

其实就是考察 synchronized 锁住的是哪个对象

情况1:12 或 21

@Slf4j(topic = "c.Number")
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(); // 在多核CPU下,主线程会把这几个线程打开,但是即使打开了,仍然会被上锁导致无法运行
    new Thread(()->{
    
     n1.b(); }).start();
}

情况2:1s后12,或 2 1s后 1

@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();
    new Thread(()->{
    
     n1.a(); }).start();
    new Thread(()->{
    
     n1.b(); }).start(); // 如果线程1先启动并sleep了,但是不会释放锁,即使2当前被分到了线程时间片,仍然没法执行
}

情况3:3 1s 12 或 23 1s 1 或 32 1s 1

@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();
  	// 主线程几乎同时打开3个线程
    new Thread(()->{
    
     n1.a(); }).start(); 
    new Thread(()->{
    
     n1.b(); }).start();
    new Thread(()->{
    
     n1.c(); }).start();
}

情况4:2 1s 后 1

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

情况5:2 1s 后 1,锁住的类对象和实例对象是不同的对象,同时执行的,在多核的情况下,一定是2先打印出来

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

情况6:1s 后12, 或 2 1s后 1, 同时锁住类对象

@Slf4j(topic = "c.Number")
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();
}

情况7:2 1s 后 1,锁不同的对象,同时执行,先打印出2

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

情况8:1s 后12, 或 2 1s后 1 ,锁住的同一个Number.class对象

@Slf4j(topic = "c.Number")
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();
}

猜你喜欢

转载自blog.csdn.net/qq_44036439/article/details/128878453