八锁问题

  1. new发短信后 睡眠100毫秒,发短信、发邮件的打印顺序
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
27
public class Test01 {
public static void main(String[] args) throws InterruptedException {
Test0101 test0101 = new Test0101();

new Thread(() -> {
test0101.sendMessage();
},"AAA").start();

Thread.sleep(100);

new Thread(() -> {
test0101.sendEmail();
},"BBB").start();
}
}
class Test0101{
public synchronized void sendMessage(){
System.out.println("sendMessage");
}
public synchronized void sendEmail(){
System.out.println("sendEmail");
}
}
结果:
sendMessage
sendEmail
因为synchronized关键字 是对该资源类的对象上锁,因此哪个线程先拿到对象锁,就先执行

2.发短信线程中执行时睡眠4秒,发短信、发邮件的打印顺序

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
27
28
29
30
31
32
public class Test02 {
public static void main(String[] args) throws InterruptedException {
Test0201 test0201 = new Test0201();

new Thread(() -> {
test0201.sendMessage();
},"AAA").start();

Thread.sleep(100);

new Thread(() -> {
test0201.sendEmail();
},"BBB").start();
}
}
class Test0201{
public synchronized void sendMessage(){
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendMessage");
}
public synchronized void sendEmail(){
System.out.println("sendEmail");
}
}
结果:
sendMessage
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
26
27
28
29
30
31
32
33
34
35
public class Test03  {
public static void main(String[] args) throws InterruptedException {
Test0301 test0301 = new Test0301();

new Thread(() -> {
test0301.sendMessage();
},"AAA").start();

Thread.sleep(100);

new Thread(() -> {
test0301.call();
},"BBB").start();
}
}
class Test0301{
public synchronized void sendMessage(){
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendMessage");
}
public synchronized void sendEmail(){
System.out.println("sendEmail");
}
public void call(){
System.out.println("call");
}
}
结果:
call
sendMessage
call()为普通方法,不受同步方法的影响,不受锁的影响

4.两个资源,发短信、发邮件的打印顺序(先邮件后短信)

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
27
28
29
30
31
32
33
34
35
public class Test04  {
public static void main(String[] args) throws InterruptedException {
Test0401 test0401 = new Test0401();
Test0401 test0402 = new Test0401();
new Thread(() -> {
test0401.sendMessage();
},"AAA").start();

Thread.sleep(100);

new Thread(() -> {
test0402.sendEmail();
},"BBB").start();
}
}
class Test0401{
public synchronized void sendMessage(){
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendMessage");
}
public synchronized void sendEmail(){
System.out.println("");
}
public void call(){
System.out.println("call");
}
}
结果:
sendEmail
sendMessage
区别于问题1,该情况是 两个资源类对象分别开启两个线程,因此锁对象 并无互相干扰,因为线程延时的原因,打电话 先输出

5.两个同步方法变静态、一个资源,发短信、发邮件的打印顺序

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
27
28
29
30
31
32
33
34
public class Test05{
public static void main(String[] args) throws InterruptedException {
Test0501 test0401 = new Test0501();
new Thread(() -> {
test0401.sendMessage();
},"AAA").start();

Thread.sleep(100);

new Thread(() -> {
test0401.sendEmail();
},"BBB").start();
}
}
class Test0501{
public static synchronized void sendMessage(){
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendMessage");
}
public static synchronized void sendEmail(){
System.out.println("sendEmail");
}
public void call(){
System.out.println("call");
}
}
结果:
sendMessage
sendEmail
加上static关键字之后,两个方法都变为静态方法。

6.两个静态同步方法、两个资源,发短信、发邮件的打印顺序

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
27
28
29
30
31
32
33
34
35
public class Test06 {
public static void main(String[] args) throws InterruptedException {
Test0601 test0601 = new Test0601();
Test0601 test0602 = new Test0601();
new Thread(() -> {
test0601.sendMessage();
},"AAA").start();

Thread.sleep(100);

new Thread(() -> {
test0602.sendEmail();
},"BBB").start();
}
}
class Test0601{
public static synchronized void sendMessage(){
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendMessage");
}
public static synchronized void sendEmail(){
System.out.println("sendEmail");
}
public void call(){
System.out.println("call");
}
}
结果:
sendMessage
sendEmail
原理同5synchronized 加 静态方法 锁的是 Class

7.一个静态同步方法、一个普通同步方法、一个资源,发短信、发邮件的打印顺序

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
27
28
29
30
31
32
33
34
public class Test07 {
public static void main(String[] args) throws InterruptedException {
Test0701 test0701 = new Test0701();
new Thread(() -> {
test0701.sendMessage();
},"AAA").start();

Thread.sleep(100);

new Thread(() -> {
test0701.sendEmail();
},"BBB").start();
}
}
class Test0701{
public static synchronized void sendMessage(){
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendMessage");
}
public synchronized void sendEmail(){
System.out.println("sendEmail");
}
public void call(){
System.out.println("call");
}
}
结果:
sendEmail
sendMessage
synchronized 锁的是 类实例即对象 、synchronized 加 静态方法 锁的是 Class

8.一个静态同步方法、一个普通同步方法、两个资源,发短信、发邮件的打印顺序

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
27
28
29
30
31
32
33
34
35
public class Test08 {
public static void main(String[] args) throws InterruptedException {
Test0801 test0801 = new Test0801();
Test0801 test0802 = new Test0801();
new Thread(() -> {
test0801.sendMessage();
},"AAA").start();

Thread.sleep(100);

new Thread(() -> {
test0802.sendEmail();
},"BBB").start();
}
}
class Test0801{
public static synchronized void sendMessage(){
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendMessage");
}
public synchronized void sendEmail(){
System.out.println("sendEmail");
}
public void call(){
System.out.println("call");
}
}
结果:
sendEmail
sendMessage
原理同7