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