8锁现象(加深synchronized锁的理解)
8个关于锁的问题
锁是什么?如何判断锁的是谁!
对象、Class
synchronized若修饰于实例方法,则锁住的是方法的对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class Demo5_synchronized锁住的是方法的对象 { public static void main(String[] args) throws InterruptedException { Phone phone = new Phone(); new Thread(()->{phone.sendSms();},"A").start(); TimeUnit.SECONDS.sleep(1); new Thread(()->{phone.call();},"B").start();
}
}
class Phone{
public synchronized void sendSms() { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("发短信"); } public synchronized void call(){ System.out.println("打电话"); } }
|
一个对象加锁之后,不影响没有synchronized修饰的方法的正常执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class Demo6_synchronized锁住对象后_没有synchronized修饰的方法正常执行 { public static void main(String[] args) throws InterruptedException { Phone2 phone = new Phone2(); new Thread(()->{phone.sendSms();},"A").start(); TimeUnit.SECONDS.sleep(1); new Thread(()->{phone.hello();},"B").start();
} } class Phone2{
public synchronized void sendSms() { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("发短信"); } public void hello(){ System.out.println("Hello"); } }
|
两个对象 两个同步方法 互不影响
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public class Demo7_synchronized_两个对象两个同步方法 { public static void main(String[] args) throws InterruptedException { Phone3 phone1 = new Phone3(); Phone3 phone2 = new Phone3(); new Thread(()->{phone1.sendSms();},"A").start(); TimeUnit.SECONDS.sleep(1); new Thread(()->{phone2.call();},"B").start();
} } class Phone3{
public synchronized void sendSms() { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("发短信"); } public synchronized void call(){ System.out.println("打电话"); } }
|
静态同步方法锁住的是类的Class对象,不影响实例方法的正常执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public class Demo8_静态同步方法锁住的是类的Class对象_不影响实例方法的正常执行 { public static void main(String[] args) throws InterruptedException { Phone4 phone = new Phone4(); new Thread(() -> { phone.sendSms(); }, "A").start(); TimeUnit.SECONDS.sleep(1); new Thread(() -> { phone.call(); }, "B").start();
} } class Phone4 {
public static synchronized void sendSms() { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("发短信"); }
public synchronized void call() { System.out.println("打电话"); } }
|
小结
同步实例方法锁住的是调用者/当前对象,会影响当前对象的所有同步实例方法的正常执行。
静态同步实例方法锁住的是类模板对象Class,会影响类的所有类方法的正常执行。
其他
TimeUnit
类
设置延迟的类,(用来代替Thread.sleep()
)
方法 |
介绍 |
TimeUnit.SECONDS.sleep(timeout) |
延时,单位:秒 |
TimeUnit.DAYS.sleep(timeout) |
延时,单位:天 |
TimeUnit.HOURS.sleep(timeout); |
延时,单位:小时 |
… |
… |