class Phone{
public static synchronized void sendSMS() throws InterruptedException {
TimeUnit.SECONDS.sleep(3);
System.out.println("*****sendSMS*");
}
public synchronized void sendEmail(){
System.out.println("*****sendEmail*");
}
public void sayHello(){
System.out.println("*****sayHello");
}
}
* 8 lock
* 1、标准访问,请问先打印邮件还是短信
* 2、暂停4秒钟在邮件方法,请问先打印邮件还是短信
* 3、新增普通 sayHello 方法,两个线程,一个调邮件一个调 sayHello,请问先打印邮件还是 Hello
* 4、两部手机,请问先打印邮件还是短信
* 5、两个静态方法,同一部手机,请问先打印邮件还是短信
* 6、两个静态方法,2部手机,请问先打印邮件还是短信
* 7、一个静态同步方法,一个普通同步方法,同一部手机,请问先打印邮件还是短信
* 8、一个静态同步方法,一个普通同步方法,2 部手机,请问先打印邮件还是短信
*/
* 1,2锁 解答:
* 一个对象如果有多个 synchronized 方法,某一时刻内,只要一个线程去调用其中的一个 synchronized 方法了,
* 其它的线程都只能等待,换句话说,某一时刻内,只能有唯一一个线程去访问这些 synchronized 方法。
*
* 虽然发短信和发邮件是两个功能,但是属于同一个资源类,锁的是当前对象 this,被锁定后,其它的线程都不能
* 进入到当前对象的其它 synchronized 方法
*
* 3锁解答:sayHello 没有synchronized 修饰,不需要争抢
* 4锁解答:两部手机,等于说两个 this 对象,各回各家,各找各妈
*
* 5、6、7、8锁解答:
* synchronized 实现同步的基础,Java 中的每一个对象都可以作为锁,具体表现为一下三种形式:
* 对于同步方法,锁是当前实例对象,锁的是当前 this
* 对于同步方法块,锁是 synchronized 括号里配置的对象,
* 对于静态方法,锁是当前类的 Class 对象,class模板只有一份
*
* 当一个线程试图访问同步代码块时,它首先必须得到锁,退出或者抛出异常时必须释放锁。
* 也就是说如果一个对象的非静态同步方法获取锁后,该实例对象的其它非静态方法同步方法必须等待获取锁的方法释放锁后才能获取锁
* 可是别的实例对象的非静态同步方法因为跟该实例对象的非静态同步方法用的是不同的锁,
* 所以无须等待该实例对象已获取锁的非静态同步方法释放锁就可以获取它们自己的锁
*
* 所有的静态同步方法用的是同一把锁--类对象 Class 本身
* 这两把锁是不同的对象,所以静态同步方法和非静态同步方法之间是不会有竟太条件的。
* 但是一旦一个静态同步方法获取锁后,其它的静态同步方法必须等待该方法释放锁后才能获取锁
* 而不管是同一个实例对象的静态同步方法之间,还是不同的实例对象的静态同步方法之间,只要它们是同一个类的实例对象
*/
public class Lock8Demo {
public static void main(String[] args) {
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(()->{
try {
phone.sendSMS();
} catch (InterruptedException e) {
e.printStackTrace();
}
},"A").start();
new Thread(()->{
phone2.sendEmail();
},"B").start();
}
}
评论