8锁问题
什么是锁?锁的对象是谁?
package com.sw.lock8;
import java.util.concurrent.TimeUnit;
/**
* @Author suaxi
* @Date 2021/1/4 15:44
* 1、执行顺序:发短信 打电话
* 2、增加睡眠时间后,执行顺序:发短信 打电话
*/
public class Test1 {
public static void main(String[] args) {
Phone1 phone1 = new Phone1();
new Thread(() ->{
phone1.sms();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() ->{
phone1.call();
},"B").start();
}
}
class Phone1{
//synchronized锁的对象是方法的调用者
//两个方法用的是同一个锁,谁先拿到锁,谁先调用
public synchronized void sms(){
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}
package com.sw.lock8;
import java.util.concurrent.TimeUnit;
/**
* @Author suaxi
* @Date 2021/1/4 15:51
* 3、增加一个hello的普通方法后,执行顺序为 hello 发短信
* 4、两个对象、两个同步方式,执行顺序为 打电话 发短信
*/
public class Test2 {
public static void main(String[] args) {
//两个对象、两个调用者、两把锁
Phone2 phone1 = new Phone2();
Phone2 phone2 = new Phone2();
new Thread(() ->{
phone1.sms();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() ->{
phone2.call();
},"B").start();
}
}
class Phone2{
//synchronized锁的对象是方法的调用者
public synchronized void sms(){
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
//普通方法不受锁的限制
public void hello(){
System.out.println("hello");
}
}
package com.sw.lock8;
import java.util.concurrent.TimeUnit;
/**
* @Author suaxi
* @Date 2021/1/4 15:58
* 5、增加static后,执行顺序为 发短信 打电话
* 6、两个Phone对象,执行顺序依然为为 发短信 打电话
*/
public class Test3 {
public static void main(String[] args) {
//两个对象的Class类模板只有一个,与问题5一样锁的也是Class
Phone3 phone = new Phone3();
Phone3 phone1 = new Phone3();
new Thread(() ->{
phone.sms();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() ->{
phone1.call();
},"B").start();
}
}
class Phone3{
//synchronized锁的对象是方法的调用者
//static静态方法,类一加载就有了,此处锁的是Class对象
public static synchronized void sms(){
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public static synchronized void call(){
System.out.println("打电话");
}
}
package com.sw.lock8;
import java.util.concurrent.TimeUnit;
/**
* @Author suaxi
* @Date 2021/1/4 16:05
* 7、1个静态同步方法,1个普通同步方法,一个对象,执行顺序 打电话 发短信
* 8、1个静态同步方法,1个普通同步方法,两个对象,执行顺序 打电话 发短信
*/
public class Test4 {
public static void main(String[] args) {
//两个对象的Class类模板只有一个,与问题5一样锁的也是Class
Phone4 phone1 = new Phone4();
Phone4 phone2 = new Phone4();
new Thread(() ->{
phone1.sms();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() ->{
phone2.call();
},"B").start();
}
}
class Phone4{
//静态同步方法 锁的是Class类模板
public static synchronized void sms(){
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
//普通同步方法 锁的是调用者,不需要再等待发短信的sleep睡眠时间,两个方法用的不是同一个锁
public synchronized void call(){
System.out.println("打电话");
}
}
小结
一个对象,拿的是同一把锁
两个对象拿的是不同的锁
加了static静态方法之后,不论有几个对象,锁的只有一个Class模板
普通方法不受锁的限制
评论 (0)