8锁,就是关于锁的8个问题
- 1、标准情况下,两个线程先打印 发短信 还是 打电话? ==1/发短信 2/打电话==
java
package com.mystpet.Test;
import java.sql.Time;
import java.util.concurrent.TimeUnit;
/*synchronized锁的是方法的调用者
* 两个方法用的同一个锁,谁先拿到谁执行*/
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) {
// throw new RuntimeException(e);
// }
new Thread(()->{
phone.call();
},"B").start();
}
}
class Phone{
public synchronized void sendSms(){
// try {
// TimeUnit.SECONDS.sleep(4);
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}- 2、sendSms延迟4秒,两个线程先打印 发短信 还是 打电话? ==1/发短信 2/打电话==
java
package com.mystpet.Test;
import java.sql.Time;
import java.util.concurrent.TimeUnit;
/*synchronized锁的是方法的调用者
* 两个方法用的同一个锁,谁先拿到谁执行*/
//锁在sendSms方法中,跟着延迟4s
public class test1 {
public static void main(String[] args) {
Phone phone=new Phone();
new Thread(()->{
phone.sendSms();
},"A").start();
new Thread(()->{
phone.call();
},"B").start();
}
}
class Phone{
public synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}- 3、增加了一个普通方法!先执行 发短信 还是 hello? ==1/hello(普通方法) 2/发短信==
java
package com.mystpet.Test;
import java.util.concurrent.TimeUnit;
public class Test2 {
public static void main(String[] args) {
Phone2 phone2=new Phone2();
new Thread(()->{
phone2.sendSms();
},"A").start();
new Thread(()->{
phone2.hello();
},"B").start();
}
}
class Phone2{
public synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
// 这里没有锁!不是同步方法,不受锁的影响
public void hello(){
System.out.println("hello");
}
}- 4、两个对象、两个同步方法,先执行 发短信 还是 打电话? ==1/打电话 2/发短信==
java
package com.mystpet.Test;
import java.util.concurrent.TimeUnit;
/*
phone1与phone2为两个对象,锁的是对象的调用者,两个对象两把锁,互不影响
*/
public class Test2 {
public static void main(String[] args) {
Phone2 phone2=new Phone2();
Phone2 phone1=new Phone2();
new Thread(()->{
phone1.sendSms();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
new Thread(()->{
phone2.call();
},"B").start();
}
}
class Phone2{
public synchronized void sendSms(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
// 这里没有锁!不是同步方法,不受锁的影响
public void hello(){
System.out.println("hello");
}
}- 5、增加两个静态的同步方法,只有一个对象,先打印 发短信 还是 打电话? ==1/发短信 2/打电话 (锁的是Class)==
java
package com.mystpet.Test;
import java.util.concurrent.TimeUnit;
public class Test3 {
public static void main(String[] args) {
// 两个对象的class类模板只有一个,static
Phone3 phone1 = new Phone3();
Phone3 phone2 = new Phone3();
// 有锁的存在
new Thread(() -> {
phone1.sendSms();
}, "A").start();
// 捕获
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
phone2.call();
}, "B").start();
}
}
class Phone3 {
// synchronized 锁的对象是方法的调用者!
// 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("打电话");
}
}- 6、两个对象!增加两个静态的同步方法,只有一个对象,先打印 发短信 还是 打电话? ==1/发短信 2/打电话 (锁的还是Class)==
java
package com.mystpet.Test;
import java.util.concurrent.TimeUnit;
/*
锁的是模板,也就是class,所以不同对象依然调用同一个锁
*/
public class Test3 {
public static void main(String[] args) {
// 两个对象的class类模板只有一个,static
Phone3 phone1 = new Phone3();
Phone3 phone2 = new Phone3();
// 有锁的存在
new Thread(() -> {
phone1.sendSms();
}, "A").start();
// 捕获
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
phone2.call();
}, "B").start();
}
}
class Phone3 {
// synchronized 锁的对象是方法的调用者!
// 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("打电话");
}
}- 7、一个静态同步方法,一个普通同步方法,只有一个对象,先打印 发短信 还是 打电话? ==1/打电话 2/发短信==
java
package com.mystpet.Test;
import java.util.concurrent.TimeUnit;
/*
类锁与调用锁互不影响,平行进行
*/
public class Test4 {
public static void main(String[] args) {
Phone4 phone1 = new Phone4();
new Thread(() -> {
phone1.sendSms();
}, "A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
phone1.call();
}, "B").start();
}
}
class Phone4 {
// 静态同步方法 锁的是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("打电话");
}
}- 8、一个静态同步方法,一个普通同步方法,两个对象,先打印 发短信 还是 打电话? ==1/打电话 2/发短信==
java
package com.mystpet.Test;
import java.util.concurrent.TimeUnit;
/*
类锁只锁static方法,调用锁只锁普通同步方法,两者不影响
*/
public class Test4 {
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 {
// 静态同步方法 锁的是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("打电话");
}
}小结
- new this 具体的一个手机
- static Class 唯一的一个模板