JUC-03-八锁现象

JUC-03-八锁现象

1. Synchronized 锁的对象问题

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.zhuuu.lock8;


// 8锁: 锁的八个问题
// 1. 标准情况下 : 发短信 打电话
// 2. 延迟四秒后: 发短信 打电话


import java.util.concurrent.TimeUnit;

public class Test1 {
public static void main(String[] args) {
Phone phone = new Phone();

// 锁的存在
new Thread(()->{
phone.sendSms();
},"A").start();

// 休息一秒
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}

new Thread(()->{
phone.call();
},"B").start();
}
}



class Phone{

// synchronized 锁的对象是方法的调用者
// 这里两个方法拿到的是同一个锁:谁先拿到 谁先执行

public synchronized void sendSms(){
// 休息一秒
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}

public synchronized void call(){
System.out.println("打电话");
}
}
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package com.zhuuu.lock8;

import java.util.concurrent.TimeUnit;

// 3. 增加了一个普通方法 先执行 hello 再执行 发短信
// 4. 两个对象,两个同步方法, 先 打电话 再 发短信 (按时间执行)

public class Test2 {
public static void main(String[] args) {
// 如果有两个对象
// 两个对象 两个调用者 两把锁!!!
Phone2 phone2 = new Phone2();
Phone2 phone1 = new Phone2();

// 锁的存在
new Thread(()->{
phone2.sendSms();
},"A").start();

// 休息一秒
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}


new Thread(()->{
phone1.call();
},"B").start();
}
}



class Phone2{

// synchronized 锁的对象是方法的调用者
// 这里两个方法拿到的是同一个锁:谁先拿到 谁先执行

public synchronized void sendSms(){
// 休息一秒
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}

public synchronized void call(){
System.out.println("打电话");
}

// 这里没有锁 不是同步方法

public void hello(){
System.out.println("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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.zhuuu.lock8;

import java.util.concurrent.TimeUnit;

//5. 增加两个静态的同步方法 (锁的是class)(发短信 打电话)
//6. 两个对象 还是两个静态同步方法 (发短信 打电话)

public class Test3 {
public static void main(String[] args) {
// 这里两个对象的Class类模板只有一个
// 锁的是同一个class
Phone3 phone3 = new Phone3();
Phone3 phone4 = new Phone3();

// 锁的存在
new Thread(()->{
phone3.sendSms();
},"A").start();

// 休息一秒
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}


new Thread(()->{
phone4.call();
},"B").start();
}
}



// Phone3 只有唯一的一个class对象

class Phone3{

// static 静态方法 (类一加载就有)
// static 这里锁的是class

public static synchronized void sendSms(){
// 休息一秒
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}

public static synchronized void call(){
System.out.println("打电话");
}
}
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.zhuuu.lock8;

import java.util.concurrent.TimeUnit;

// 7. 一个静态同步方法 一个普通同步方法 一个对象( 打电话 发短信)
// 8. 一个静态同步方法 一个普通同步方法 两个对象( 打电话 发短信)

public class Test4 {
public static void main(String[] args) {
// 这里两个对象的Class类模板只有一个
// 锁的是同一个class
Phone4 phone1 = new Phone4();
Phone4 phone2 = new Phone4();

// 锁的存在
new Thread(()->{
phone1.sendSms();
},"A").start();

// 休息一秒
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}


new Thread(()->{
phone2.call();
},"B").start();
}
}


class Phone4{

// static 静态方法 (类一加载就有)
// static 这里锁的是class

// 静态的同步方法 锁的是class类模板
public static synchronized void sendSms(){
// 休息一秒
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}

// 普通的同步方法 锁的是调用者
public synchronized void call(){
System.out.println("打电话");
}
}

2. 小结

  • new : 具体的一个实例
  • static : class模板

(本质上:两个拿到的锁不一样)

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2019-2022 Zhuuu
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信