八锁现象
一、简介
- synchronized 锁的对象是方法的调用者
- 两个方法用的是同一个锁,谁先拿到谁执行
- 普通的方法是用对象操作的(同步方法 对象)
- static静态方法是用Class操作的(静态同步方法 Class)
- new this 具体的一个手机
- static Class 唯一的一个模板
八种情况:
两个同步方法,一个对象(发短信,打电话)
两个同步方法,一个对象,发短信延迟(发短信,打电话)
一个同步方法,一个普通方法,一个对象,同步方法延迟(打电话,发短信)
两个同步方法,两个对象,发短信延迟(打电话,发短信)
两个静态同步方法,一个对象,发短信延迟(发短信,打电话)
两个静态同步方法,两个对象,发短信延迟(发短信,打电话)
一个静态同步方法,一个普通同步方法,一个对象,静态同步方法延迟(打电话,发短信)
一个普通同步方法,一个静态同步方法,两个对象,静态同步方法延迟(打电话,发短信)
二、代码案例
1、案例1
package com.sgz.lock8;
import java.util.concurrent.TimeUnit;
/**
* 日期:2022/8/30 - 10:34
* 需求:两个同步方法,一个对象(发短信,打电话)
*/
public class Lock01 {
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() {
System.out.println("发短信");
}
public synchronized void call() {
System.out.println("打电话");
}
}
2、案例2
package com.sgz.lock8;
import java.util.concurrent.TimeUnit;
/**
* 日期:2022/8/30 - 10:34
* 需求:两个同步方法,一个对象,发短信延迟(发短信,打电话)
*/
public class Lock02 {
public static void main(String[] args) {
Phone2 phone = new Phone2();
// 锁的存在
new Thread(() -> {
phone.sendSms();
}, "A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
phone.call();
}, "B").start();
}
}
class Phone2 {
// synchronized 锁的对象是方法的调用者
// 两个方法用的是同一个锁,谁先拿到谁执行
public synchronized void sendSms() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call() {
System.out.println("打电话");
}
}
3、案例3
package com.sgz.lock8;
import java.util.concurrent.TimeUnit;
/**
* 日期:2022/8/30 - 10:34
* 需求:一个同步方法,一个普通方法,一个对象,同步方法延迟(hello,发短信)
*/
public class Lock03 {
public static void main(String[] args) {
Phone3 phone = new Phone3();
new Thread(() -> {
phone.sendSms();
}, "A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
phone.call();
}, "B").start();
}
}
class Phone3 {
public synchronized void sendSms() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
// 没有锁,不是同步方法,不受锁的影响
public void call() {
System.out.println("打电话");
}
}
4、案例4
package com.sgz.lock8;
import java.util.concurrent.TimeUnit;
/**
* 日期:2022/8/30 - 10:34
* 需求:两个同步方法,两个对象,发短信延迟(打电话,发短信)
*/
public class Lock04 {
public static void main(String[] args) {
// 两个对象,两个调用者,两把锁,与时间无关
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 {
// synchronized 锁的对象是方法的调用者
// 两个方法用的是同一个锁,谁先拿到谁执行
public synchronized void sendSms() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call() {
System.out.println("打电话");
}
}
5、案例5
package com.sgz.lock8;
import java.util.concurrent.TimeUnit;
/**
* 日期:2022/8/30 - 10:34
* 需求:两个静态同步方法,一个对象,发短信延迟(发短信,打电话)
*/
public class Lock05 {
public static void main(String[] args) {
Phone5 phone = new Phone5();
new Thread(() -> {
phone.sendSms();
}, "A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
phone.call();
}, "B").start();
}
}
class Phone5 {
// static 静态方法
// 类一加载就有了,锁的是Class
public static synchronized void sendSms() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public static synchronized void call() {
System.out.println("打电话");
}
}
6、案例6
package com.sgz.lock8;
import java.util.concurrent.TimeUnit;
/**
* 日期:2022/8/30 - 10:34
* 需求:两个静态同步方法,两个对象,发短信延迟(发短信,打电话)
*/
public class Lock06 {
public static void main(String[] args) {
// 两个对象的Class类模板只有一个,static,锁的是Class类Phone6
Phone6 phone1 = new Phone6();
Phone6 phone2 = new Phone6();
new Thread(() -> {
phone1.sendSms();
}, "A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
phone2.call();
}, "B").start();
}
}
// Phone6 唯一的一个 Class 对象
class Phone6 {
// static 静态方法
// 类一加载就有了,锁的是Class
public static synchronized void sendSms() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public static synchronized void call() {
System.out.println("打电话");
}
}
7、案例7
package com.sgz.lock8;
import java.util.concurrent.TimeUnit;
/**
* 日期:2022/8/30 - 10:34
* 需求:一个静态同步方法,一个普通同步方法,一个对象,静态同步方法延迟(打电话,发短信)
*/
public class Lock07 {
public static void main(String[] args) {
Phone7 phone = new Phone7();
new Thread(() -> {
phone.sendSms();
}, "A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
phone.call();
}, "B").start();
}
}
class Phone7 {
// 静态同步方法,锁的是Class类模板
public static synchronized void sendSms() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
// 普通同步方法,锁的是调用者
public synchronized void call() {
System.out.println("打电话");
}
}
8、案例8
package com.sgz.lock8;
import java.util.concurrent.TimeUnit;
/**
* 日期:2022/8/30 - 10:34
* 需求:一个普通同步方法,一个静态同步方法,两个对象,静态同步方法延迟(打电话,发短信)
*/
public class Lock08 {
public static void main(String[] args) {
// 两个对象的Class类模板只有一个,static,锁的是Class类Phone6
Phone8 phone1 = new Phone8();
Phone8 phone2 = new Phone8();
new Thread(() -> {
phone1.sendSms();
}, "A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
phone2.call();
}, "B").start();
}
}
class Phone8 {
// static 静态方法
// 类一加载就有了,锁的是Class
public static synchronized void sendSms() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call() {
System.out.println("打电话");
}
}