乐趣区

关于juc:JUC之多线程锁的8个问题分析

  1. 程序代码

package com.atguigu.thread;import java.util.concurrent.TimeUnit;class Phone{public synchronized void sendSMS() throws Exception{System.out.println(“——sendSMS”);}public synchronized void sendEmail() throws Exception{System.out.println(“——sendEmail”);}public void getHello(){System.out.println(“——getHello”);}}/* @Description: 8 锁 @author xialei1 规范拜访,先打印短信还是邮件 2 停 4 秒在短信办法内,先打印短信还是邮件 3 新增一般的 hello 办法,是先打短信还是 hello4 当初有两部手机,先打印短信还是邮件 5 两个动态同步办法,1 部手机,先打印短信还是邮件 6 两个动态同步办法,2 部手机,先打印短信还是邮件 7 1 个动态同步办法 1 个一般同步办法,1 部手机,先打印短信还是邮件 8 1 个动态同步办法 1 个一般同步办法,2 部手机,先打印短信还是邮件 ———————————/public class Lock_8{public static void main(String[] args) throws Exception{Phone phone = new Phone();Phone phone2 = new Phone();new Thread(() -> {try {phone.sendSMS();} catch (Exception e) {e.printStackTrace();}}, “AA”).start();Thread.sleep(100);new Thread(() -> {try {phone.sendEmail();//phone.getHello();//phone2.sendEmail();} catch (Exception e) {e.printStackTrace();}}, “BB”).start();}}

  1. 锁的 8 个问题

(1) 规范拜访,先打印短信还是邮件

(2) 停 4 秒在短信办法内,先打印短信还是邮件

(3) 一般的 hello 办法,是先打短信还是 hello

(4) 当初有两部手机,先打印短信还是邮件

(5) 两个动态同步办法,1 部手机,先打印短信还是邮件

(6) 两个动态同步办法,2 部手机,先打印短信还是邮件

(7) 1 个动态同步办法,1 个一般同步办法,1 部手机,先打印短信还是邮件

(8) 1 个动态同步办法,1 个一般同步办法,2 部手机,先打印短信还是邮件

  1. 锁的 8 个问题剖析

一个对象外面如果有多个 synchronized 办法,某一个时刻内,java 培训只有一个线程去调用其中的一个 synchronized 办法了,其它的线程都只能期待,换句话说,某一个时刻内,只能有惟一一个线程去拜访这些 synchronized 办法。

锁的是以后对象 this,被锁定后,其它的线程都不能进入到以后对象的其它的 synchronized 办法。

加个一般办法后发现和同步锁无关。

换成两个对象后,不是同一把锁了,状况立即变动。

synchronized 实现同步的根底:Java 中的每一个对象都能够作为锁。

具体表现为以下 3 种模式。

对于一般同步办法,锁是以后实例对象。

对于动态同步办法,锁是以后类的 Class 对象。

对于同步办法块,锁是 Synchonized 括号里配置的对象

当一个线程试图拜访同步代码块时,它首先必须失去锁,退出或抛出异样时必须开释锁。

也就是说如果一个实例对象的非动态同步办法获取锁后,该实例对象的其余非动态同步办法必须期待获取锁的办法开释锁后能力获取锁,可辨认的实例对象的非动态同步办法因为跟该实例对象的非动态同步办法用的是不同的锁,所以毋须期待该实例对象已获取锁的非动态同步办法开释锁就能够获取他们本人的锁。

所有的动态同步办法用的也是同一把锁——类对象自身,这两把锁是两个不同的对象,所以动态同步办法与非动态同步办法之间是不会有竞态条件的。然而一旦一个动态同步办法获取锁后,其余的动态同步办法都必须期待该办法开释锁后能力获取锁,而不论是同一个实例对象的动态同步办法之间,还是不同的实例对象的动态同步办法之间,只有它们同一个类的实例对象!

关键词:java 培训

退出移动版