天天看点

线程八锁情况一情况二情况三情况四情况五情况六情况七情况八

情况一

@Slf4j(topic = "c.Number")
class Number {
    public synchronized void a() {
        log.debug("1");
    }
    public synchronized void b() {
        log.debug("2");
    }
}
public class Main {
    public static void main(String[] args) {
        Number number = new Number();
        new Thread(() -> {number.a();}).start();
        new Thread(() -> {number.b();}).start();
    }
}
           

在这种情况里$synchronized$锁住的都是$this$对象,即$number$,因此这个题执行时,结果为$1,2$或者$2,1$且大概率是$1,2$

情况二

@Slf4j(topic = "c.Number")
class Number {
    public synchronized void a() {
        log.debug("1");
    }
    public synchronized void b() {
	    sleep(1);
        log.debug("2");
    }

}
public class Main {
    public static void main(String[] args) {
        Number number = new Number();
        new Thread(() -> {number.a();}).start();
        new Thread(() -> {number.b();}).start();
    }
}
           

这种情况与第一种相同,只是多了一个睡眠,因此结果为,延迟一秒打印$2,1$或者$1$延迟一秒$2$

情况三

@Slf4j(topic = "c.Number")
class Number {
    public synchronized void a() {
        log.debug("1");
    }
    public synchronized void b() throws InterruptedException {
        Thread.sleep(1000);
        log.debug("2");
    }
    public void c() {
        log.debug("3");
    }
}
public class Main {
    public static void main(String[] args) {
        Number number = new Number();
        new Thread(() -> {number.a();}).start();
        new Thread(() -> {number.b();}).start();
        new Thread(() -> {number.c();}).start();
    }
}
           

这种情况里多了一个方法$c()$,但是他没有被对象锁限制,因此它一定打印,所以情况有

打印$1,3$一秒后打印$2$

打印$3,1$一秒后打印$2$

打印3一秒后打印$2, 1$

情况四

@Slf4j(topic = "c.Number")
class Number {
    public synchronized void a() {
        log.debug("1");
    }
    public synchronized void b() throws InterruptedException {
        Thread.sleep(1000);
        log.debug("2");
    }
}
public class Main {
    public static void main(String[] args) {
        Number number1 = new Number();
        Number number2 = new Number();
        new Thread(() -> {number1.a();}).start();
        new Thread(() -> {number2.b();}).start();
    }
}
           

这种情况下,是两个不同的对象调用的方法,因此压根没有互斥,所以一定是先打印$1$一秒后打印$2$

情况五

@Slf4j(topic = "c.Number")
class Number {
    public synchronized void a() {
        log.debug("1");
    }
    public static synchronized void b() throws InterruptedException {
        Thread.sleep(1000);
        log.debug("2");
    }
}
public class Main {
    public static void main(String[] args) {
        Number number1 = new Number();
        new Thread(() -> {number1.a();}).start();
        new Thread(() -> {number1.b();}).start();
    }
}
           

这里方法$b$被$static$修饰,因此他锁住的实际上是类对象,所以这两个也不互斥,所以一定是先打印$1$,一秒后再打印$2$

情况六

@Slf4j(topic = "c.Number")
class Number {
    public static synchronized void a() {
        log.debug("1");
    }
    public static synchronized void b() throws InterruptedException {
        Thread.sleep(1000);
        log.debug("2");
    }
}
public class Main {
    public static void main(String[] args) {
        Number number1 = new Number();
        new Thread(() -> {number1.a();}).start();
        new Thread(() -> {number1.b();}).start();
    }
}
           

情况七

@Slf4j(topic = "c.Number")
class Number {
    public synchronized void a() {
        log.debug("1");
    }
    public static synchronized void b() throws InterruptedException {
        Thread.sleep(1000);
        log.debug("2");
    }
}
public class Main {
    public static void main(String[] args) {
        Number number1 = new Number();
        Number number2 = new Number();
        new Thread(() -> {number1.a();}).start();
        new Thread(() -> {number2.b();}).start();
    }
}
           

情况八

@Slf4j(topic = "c.Number")
class Number {
    public static synchronized void a() {
        log.debug("1");
    }
    public static synchronized void b() throws InterruptedException {
        Thread.sleep(1000);
        log.debug("2");
    }
}
public class Main {
    public static void main(String[] args) {
        Number number1 = new Number();
        Number number2 = new Number();
        new Thread(() -> {number1.a();}).start();
        new Thread(() -> {number2.b();}).start();
    }
}
           

继续阅读