Synchronized案例

Synchronized 案例

两个普通同步方法,先打印邮件还是短信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Phone {
public synchronized void sendEmail() {
System.out.println("-------sendEmail");
}

public synchronized void sendSMS() {
System.out.println("-------sendSMS");
}

public static void main(String[] args) {
Phone phone = new Phone();
new Thread(phone::sendEmail, "a").start();
try {
TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(phone::sendSMS, "b").start();
}
}

先打印邮件,因为一个对象里面如果有多个 synchronized 方法,某一个时刻内,只要一个线程去调用其中的一个 synchronized 方法,其它的线程都只能等待,换句话说,某一个时刻内,只能有唯一的一个线程去访问这些 synchronized 方法,锁的是当前对象 this,被锁定后,其它的线程都不能进入到当前对象的其它的 synchronized 方法

sendEmail 方法暂停 3 秒钟,先打印邮件还是短信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Phone {
public synchronized void sendEmail() {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("-------sendEmail");
}

public synchronized void sendSMS() {
System.out.println("-------sendSMS");
}

public static void main(String[] args) {
Phone phone = new Phone();
new Thread(phone::sendEmail, "a").start();
try {
TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(phone::sendSMS, "b").start();
}
}

先打印邮件,同上,而且 sleep 不会释放锁

新增一个普通的方法 hello,先打印邮件还是短信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Phone {
public synchronized void sendEmail() {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("-------sendEmail");
}

public void hello() {
System.out.println("-------sendSMS");
}

public static void main(String[] args) {
Phone phone = new Phone();
new Thread(phone::sendEmail, "a").start();
try {
TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(phone::hello, "b").start();
}
}

先打印短信,调用普通方法与同步锁无关

两个对象,先打印邮件还是信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Phone {
public synchronized void sendEmail() {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("-------sendEmail");
}

public synchronized void sendSMS() {
System.out.println("-------sendSMS");
}

public static void main(String[] args) {
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(phone::sendEmail, "a").start();
try {
TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(phone2::sendSMS, "b").start();
}
}

先打印短信,因为是两个对象,使用的不是同一把锁

同一个对象,两个静态同步方法,先打印邮件还是短信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Phone {
public static synchronized void sendEmail() {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("-------sendEmail");
}

public static synchronized void sendSMS() {
System.out.println("-------sendSMS");
}

public static void main(String[] args) {
Phone phone = new Phone();
new Thread(Phone::sendEmail, "a").start();
try {
TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(Phone::sendSMS, "b").start();
}
}

先打印邮件,因为是类锁,锁的是当前类的 Class 对象

不同的对象,两个静态同步方法,先打印邮件还是短信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Phone {
public static synchronized void sendEmail() {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("-------sendEmail");
}

public static synchronized void sendSMS() {
System.out.println("-------sendSMS");
}

public static void main(String[] args) {
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(Phone::sendEmail, "a").start();
try {
TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(Phone::sendSMS, "b").start();
}
}

先打印邮件,同上

一个静态同步方法,一个普通同步方法,先打印邮件还是短信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Phone {
public static synchronized void sendEmail() {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("-------sendEmail");
}

public synchronized void sendSMS() {
System.out.println("-------sendSMS");
}

public static void main(String[] args) {
Phone phone = new Phone();
new Thread(Phone::sendEmail, "a").start();
try {
TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(phone::sendSMS, "b").start();
}
}

先打印短信,因为这两把锁是不同的对象,普通同步方法锁的是实例对象 this,静态同步方法锁的是唯一模板 Class,所以静态同步方法与普通同步方法之间是不会有竞态条件的

两个对象,一个静态同步方法,一个普通同步方法,先打印邮件还是短信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Phone {
public static synchronized void sendEmail() {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("-------sendEmail");
}
public synchronized void sendSMS() {
System.out.println("-------sendSMS");
}

public static void main(String[] args) {
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(Phone::sendEmail, "a").start();
try {
TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(phone2::sendSMS, "b").start();
}
}

先打印短信,同上