1、学习不用心,骗人又骗己;
2、学习不刻苦,纸上画老虎;
3、学习不惜时,终得人耻笑;
4、学习不复习,不如不学习;
5、学习不休息,毁眼伤身体;
7、狗才等着别人喂,狼都是自己寻找食物;
(问题回顾:什么是锁?到底锁的谁?要么锁new出来的对象,要么是Class,下面详解)
(8锁就是关于锁的8个问题)
①标准情况下,两个线程是先打印发短信还是打电话?答:先发短信,后打电话;为什么?因为锁,详解见注释;
②让发短信方法睡4秒,是先发短信还是先打电话?答:还是先发短信,后打电话;为什么?因为锁,详解见注释;
package com.zibo.lock8;
import java.util.concurrent.TimeUnit;
/**
* 8锁:关于锁的8个问题
* 1、标准情况下,两个线程是先打印发短信还是打电话?答:先发短信,后打电话;为什么?因为锁,详解见注释
* 2、让发短信方法睡4秒,是先发短信还是先打电话?答:还是先发短信,后打电话;为什么?因为锁,详解见注释
*/
public class Test {
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
//两个线程,一个发短信,一个打电话
new Thread(phone::sendSms,"A").start();
//中间休息1s
TimeUnit.SECONDS.sleep(1);
new Thread(phone::call,"B").start();
}
}
class Phone{
//synchronized锁的对象是方法的调用者!
//由于方法执行的时候拿到的是同一把锁,所以谁先拿到锁谁先执行
public synchronized void sendSms() throws InterruptedException {
//中间休息4s
TimeUnit.SECONDS.sleep(4);
System.out.println("发短信!");
}
public synchronized void call(){
System.out.println("打电话!");
}
}
发短信!
打电话!
synchronized锁的对象是方法的调用者!由于方法执行的时候拿到的是同一把锁,所以谁先拿到锁谁先执行,无论发短信睡了多长时间,发短信没有释放锁,打电话都不会执行;
A线程调用加了synchronized的发短信方法,B线程调用未加synchronized的hello方法,现在这种情况是先发短信,还是先say hello?
package com.zibo.lock8;
import java.util.concurrent.TimeUnit;
/**
* 8锁:关于锁的8个问题
* 3、A线程调用加了synchronized的发短信方法,B线程调用未加synchronized的hello方法,现在这种情况是先发短信,还是先say hello?答:先hello
* 4、
*/
public class Test02 {
public static void main(String[] args) throws InterruptedException {
Phone02 phone = new Phone02();
//两个线程,一个发短信,一个打电话
new Thread(() -> {
try {
phone.sendSms();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "A").start();
//中间休息1s
TimeUnit.SECONDS.sleep(1);
new Thread(phone::hello,"B").start();
}
}
class Phone02{
//synchronized锁的对象是方法的调用者!
//由于方法执行的时候拿到的是同一把锁,所以谁先拿到锁谁先执行
public synchronized void sendSms() throws InterruptedException {
//中间休息4s
TimeUnit.SECONDS.sleep(4);
System.out.println("发短信!");
}
public synchronized void call(){
System.out.println("打电话!");
}
//答案解析:先hello,因为hello这里没锁,发短信把锁拿走了,不管hello什么事
public void hello(){
System.out.println("say hello!");
}
}
say hello!
发短信!
先hello,因为hello这里没锁,发短信把锁拿走了,不管hello什么事;
使用两个对象,调用发短信和打电话,谁先执行?
package com.zibo.lock8;
import java.util.concurrent.TimeUnit;
/**
* 8锁:关于锁的8个问题
* 3、A线程调用加了synchronized的发短信方法,B线程调用未加synchronized的hello方法,现在这种情况是先发短信,还是先say hello?答:先hello
* 4、使用两个对象,调用发短信和打电话,谁先执行?答:先打电话,后发短信;
*/
public class Test02 {
public static void main(String[] args) throws InterruptedException {
//使用两个对象,调用发短信和打电话,谁先执行?
Phone02 phone1 = new Phone02();
Phone02 phone2 = new Phone02();
//两个线程,一个发短信,一个打电话
new Thread(() -> {
try {
phone1.sendSms();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "A").start();
//中间休息1s
TimeUnit.SECONDS.sleep(1);
new Thread(phone2::call,"B").start();
}
}
class Phone02{
//synchronized锁的对象是方法的调用者!
//由于方法执行的时候拿到的是同一把锁,所以谁先拿到锁谁先执行
public synchronized void sendSms() throws InterruptedException {
//中间休息4s
TimeUnit.SECONDS.sleep(4);
System.out.println("发短信!");
}
//使用两个对象,谁先执行?答:先打电话,后发短信;
//因为不同的锁,锁的是不同的对象,相互没有关系,这个时候就看先执行到到哪句打印语句了
//发短信睡了4秒,显然先执行到打电话
public synchronized void call(){
System.out.println("打电话!");
}
//答案解析:先hello,因为hello这里没锁,发短信把锁拿走了,不管hello什么事
public void hello(){
System.out.println("say hello!");
}
}
打电话!
发短信!
使用两个对象,谁先执行?答:先打电话,后发短信; 因为不同的锁对象,相互没有关系,这个时候就看先执行到到哪句打印语句了,发短信睡了4秒,显然先执行到打电话;
增加两个静态的同步方法,是先发短信还是先打电话?
package com.zibo.lock8;
import java.util.concurrent.TimeUnit;
/**
* 8锁:关于锁的8个问题
* 5、增加两个静态的同步方法,是先发短信还是先打电话?答:先发短信
*/
public class Test03 {
public static void main(String[] args) throws InterruptedException {
//两个线程,一个发短信,一个打电话
new Thread(() -> {
try {
Phone03.sendSms();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "A").start();
//中间休息1s
TimeUnit.SECONDS.sleep(1);
new Thread(Phone03::call,"B").start();
}
}
class Phone03{
//synchronized锁的对象是方法的调用者!静态方法锁的是类
//static方法,类已加载就有了,锁的是class类文件,Phone03只有唯一的一个class类文件
//由于方法执行的时候拿到的是同一把锁,所以谁先拿到锁谁先执行
//Class<Phone03> phone03Class = Phone03.class;//这个class是全局唯一的,static锁的就是这个对象
public static synchronized void sendSms() throws InterruptedException {
//中间休息4s
TimeUnit.SECONDS.sleep(4);
System.out.println("发短信!");
}
public static synchronized void call(){
System.out.println("打电话!");
}
}
发短信!
打电话!
synchronized锁的对象是方法的调用者!静态方法锁的是类;
static方法,类已加载就有了,锁的是class类文件,Phone03这个类只有唯一的一个class类文件;
Class<Phone03> phone03Class = Phone03.class;//这个class是全局唯一的,static锁的就是这个对象;
由于方法执行的时候拿到的是同一把锁,所以谁先拿到锁谁先执行;
使用两个Phone04的对象进行调用静态方法,是先发短信还是先打电话?
package com.zibo.lock8;
import java.util.concurrent.TimeUnit;
/**
* 8锁:关于锁的8个问题
* 5、增加两个静态的同步方法,是先发短信还是先打电话?答:先发短信
* 6、使用两个Phone04的对象进行调用静态方法,是先发短信还是先打电话?答:还是先发短信
* 静态方法锁的是类,与对象无关!
*/
public class Test04 {
public static void main(String[] args) throws InterruptedException {
//使用两个Phone04的对象进行调用静态方法
//答案解析:静态方法锁的是类,与对象无关!
Phone04 phone1 = new Phone04();
Phone04 phone2 = new Phone04();
//两个线程,一个发短信,一个打电话
new Thread(() -> {
try {
phone1.sendSms();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "A").start();
//中间休息1s
TimeUnit.SECONDS.sleep(1);
new Thread(() -> phone2.call(),"B").start();
}
}
class Phone04{
//synchronized锁的对象是方法的调用者!静态方法锁的是类
//static方法,类已加载就有了,锁的是class类文件,Phone03只有唯一的一个class类文件
//由于方法执行的时候拿到的是同一把锁,所以谁先拿到锁谁先执行
//Class<Phone03> phone03Class = Phone03.class;//这个class是全局唯一的,static锁的就是这个对象
public static synchronized void sendSms() throws InterruptedException {
//中间休息4s
TimeUnit.SECONDS.sleep(4);
System.out.println("发短信!");
}
public static synchronized void call(){
System.out.println("打电话!");
}
}
发短信!
打电话!
静态方法锁的是类,与对象无关!
一个静态同步方法、一个普通同步方法,一个对象调用,是先发短信还是先打电话?
一个静态同步方法、一个普通同步方法,两个对象调用,是先发短信还是先打电话?
package com.zibo.lock8;
import java.util.concurrent.TimeUnit;
/**
* 8锁:关于锁的8个问题
* 7、一个静态同步方法、一个普通同步方法,一个对象调用,是先发短信还是先打电话?答:先打电话!
* 为什么先打电话呢?因为静态方法锁的是Phone05类,普通方法锁的是phone对象,两把锁,互不影响,发短信睡眠4s,打电话肯定先执行完;
* 8、一个静态同步方法、一个普通同步方法,两个对象调用,是先发短信还是先打电话?答:先打电话!
* (非常简单易懂,代码里面就不体现了)
* 为什么先打电话呢?道理是一样的!两把锁,互不影响!
*/
public class Test05 {
public static void main(String[] args) throws InterruptedException {
//使用两个Phone04的对象进行调用静态方法
//答案解析:静态方法锁的是类,与对象无关!
Phone05 phone = new Phone05();
//两个线程,一个发短信,一个打电话
new Thread(() -> {
try {
phone.sendSms();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "A").start();
//中间休息1s
TimeUnit.SECONDS.sleep(1);
new Thread(phone::call,"B").start();
}
}
class Phone05{
//静态同步方法
public static synchronized void sendSms() throws InterruptedException {
//中间休息4s
TimeUnit.SECONDS.sleep(4);
System.out.println("发短信!");
}
//普通同步方法
public synchronized void call(){
System.out.println("打电话!");
}
}
打电话!
发短信!
因为静态方法锁的是Phone05类,普通方法锁的是phone对象,两把锁,互不影响,发短信睡眠4s,打电话肯定先执行完;