00:00
来同学们呢,咱们开始上课啊,我们这个上午呢,在最后的时候啊,我们呢。呃,写了一个例子是不是,诶这个例子呢,其实就是关于多线程对同一个账户进行取款的一个操作。那么这个程序呢?我们再来回顾一下好吧。我们在这里呢,写了一个类叫account账户,里面有账号和余额无参的构造方法,有参数的构造方法,包括set方法,Get方法,那么再往下呢,是关于一个取款的方法withdraw,那传一个参数呢,就是取多少钱是不是,那我这里呢,写了一个synchronized synchronized的括,小括号开始,大括号开始,大括号结束,对不对?那么在这个语法当中呢,我们称为同步代码框啊,同步代码框,那这就是我们当前的这个类,在我们的这个县城当中啊,我们对我们这个账户呢,进行取款操作。啊对,我们账户,那么账户呢这块呢,我们就调了我们的visraw方法是不是然后取款,那取款之后呢,我们最后呢,会输出一个什么呀?哎,这个信息,呃,那么我们之前写的这个例子,它存在什么呀?线程安全问题是吧?这个例子它就解决了线程安全问题啊为什么说解决了线程安全问题,就是这个synchronized。
01:16
SYNCH呢,它只要是只要是遇到这个synch ne的关键字之后啊,它就进入了线程同步模式。那么假如说有一个线程过来,假如说是T1吧,那么T1过来之后呢,他遇到这个关键字之后呢,他就会找什么呀,找后面这个对象的对象,所大家注意,在我们Java语言中,Java对象都有一把锁,每一个Java对象都有一把锁,各位。那么synchronized过来之后呢,他会把这个共这个共享对象,这个对象它所那个,嗯,他对的那把锁就占有了,占有之后呢,接下来就执行大块里边代码。那么在执行过程当中呢,另外的一个线程呢,它遇到snch ne之后,他也会去占有这个对应的对象所,但是这个对象所已经被另外一个线程占有了,所以这个时候呢,他只能在这个同步代码块外边等待。
02:06
当第一个T1线程把这个代码执行结束之后,会归还这个占有的这个对象的对象所。归还之后呢,在这个SNCH外边等待的这个TR线程就此时就拿到了我们这个共享对象的对象组,拿到之后呢,他就进去执行。它其实这个原理类似于什么呢?类似于假如说我们这个大楼里边只有一个洗手间,洗手间里面只有一个坑位。那么我们并发肯定会有安全问题,是不是,所以呢,我们怎么办呢?哎,我们到了洗手间之后呢,诶,你进去之后啊。你要把门锁上,这样的话第二个人就进不来了。等你解决完问题之后,你出去,你要把门打开对吧,第二个人他才能进去,第二个人进去的时候,他也会把门怎么着啊锁上。这样的话就可以达到什么呢?啊,就可以达到什么呢,我们这个排队执行的一个效果,或者叫线程同步的这种效果。
03:02
那这个其实跟这个去洗手间是一个道理啊,是一个道理。那你想象一下是不是这样的啊,如果这个大厦里边很多员工只有一个洗手间,是不是,那我们要去排队呀?对吧,哎,不能并发,我们得排队执行。那是一个道理,各位啊,是一样的。我再来再解释一下这个原理,各位啊,原理是这样的,首先呢,你需要知道一个知识点,什么知识点呢?就是它是怎么保证现场安全的,在Java源中任何一个对象啊,都有一把锁啊,在Java语言中啊,任何一个对象啊。都有一把锁啊,都有一把锁。其实这把锁呀,啊,嗯,就是一个标记啊,就是一个标记。明白吧,其实这把锁就是一个标记,只是把它叫做锁啊。只是把它叫做锁。
04:04
注意啊,100个对象。180。一个对象一把锁。你要注意这个事儿啊,那以下这个代码,以下代码的执行原理是什么呢。它的执行原理是什么呢?是T1假设啊,假设T1和T2线程并发。啊,开始执行以下代码的时候。肯定有一个先,一个后。啊,假设T1先执行了。对吧,遇到了谁呀。Sized。这个时候啊,自动找什么呀,找后面共享对象的对象锁。
05:08
啊,对象锁。找到之后。并占有这把锁。然后执行同步代码块中的程序。在程序执行过程中,一直都是占有这把锁的。直到什么时候啊,直到同步代码块。就这个框的程序执行结束了啊,直到同步代码块代码结束,这把锁才会释放。嗯。假设T1已经什么呀?哎,占有了这把锁,此时T2也遇到了什么,也遇到了synchronized关键字。
06:06
也会去占有什么啊,后面共享对象的什么,哎,这把锁。结果这把锁被什么呀,被T1占有。对吧,T2只能在同步代码块外面等待T1的。结束啊,直到T1把什么呀,同步代码块执行结束了,T一会归还什么呀?哎,这把锁此时T2终于等到明白吧,哎,此时T2终于等到这把锁。啊,这把锁。然后T2占有这把锁之后进入同步代码块执行程序。这样。
07:07
这样啊,就达到了什么,达到了县城排队之行。啊,这样就达到了县城排队执行,那么这里需要注意的是,这里需要注意的是。这个共享对象一定要选好了。啊,这个共享对象一定要选好了。这个共享对象一定是。你需要排队执行的这些线程对象所共享的。就像我上面所说的,你有T1 T2 T3 T4、T5线程,你可能只需要T1 T2、T3去排队,T4和T5不需要排队,那你就找一个T1、T2、T3这个线程能够共享的对象,你放到这儿。如果说你T4和T5过来之后。
08:01
由于T4和T5他们这两个线程不共享我们T1 T2 T3所共享的对象,假如说T1 T2 T3它共享一个对象A。对吧,那这个时候这个线程同步对T1 T2 T3是起作用的,如果我们现在T4在T5执行这个程序的时候,这个对象并不是共享的,并不是我们这个T1 T2T3共享的那个A是B,对吧?那这个时候我们T4和T5它是不会同步的。他会异步,各位他会异步啊,我现在说一下啊,就是说呀,这个共享对象很重要,这个共享对象是你需要排队的那几个线程,它所共享的对象。你明白吧?啊,一定要注意这个事儿。就这个对象,它肯定是多线程共享的,而且是你这几个线程需要排队的。
09:03
就相当于说这是一个洗手间。对吧,洗手间呢,这里有一个门呗。这里有一个门。对吧,门上呢,有一把锁,抽象化抽象化啊。你哥们呢,从这过来了?是不是,哎,啊,那哥们啊。他要进去啊,这里只有一个坑位啊。是不是,哎,那这哥们怎么着他就进去了。他把门打开啊,打开之后他又进去了,进去之后怎么办呢?他把门锁了,明白吧,这个门给他锁住了。那如果这个时候外边再来一个,那对不起他怎么办呀?哎,他只能等。他只能等。啊,大概画一下啊,因为锁住了呀,那这个呢,这哥们怎么着啊,他结束了。
10:02
结束之后出去了呀,他出去的时候,他肯定会把这个门打开,他就出去了,那这个时候呢,这哥们一看,哎,门开了他怎么办呀,他再进去。明白什么意思吧,哎,那你要注意啊,如果。你这个人和这个人确实共享的是同一个坑位。那么才会排队啊。如果你又来个这边还有一个洗手间,里边也只有一个什么呀坑位。如果你是去这里。而他呢,是去这里,对不起,你们俩不用排队。因为你们不共享对象。所以这个共享的对象很重要。这个共享的对象很重要,如果不是共享的对象,那就不行了。必须得是多线程共享对象才可以。
11:04
啊,所以现在这个程序呢。只有一个游戏机,好几个人要要玩就要轮流排队玩啊,就这意思来我们执行一下,大家看这个这个程序就是排队的呀。对吧,排队取款他不能并发了,效率低了,但是安全了,但是安全了,这是single它的实现原理。那如果说是在这个线程的生命周期上的话,它应该是怎样的呢?我们可以把这个状态图啊,再给它,哎。加点东西。加点东西啊,大家看。那当我们处于运行状态的线程遇到了一个关键字。啊叫synchronized,它会进入一个什么呀,锁持进行等待,你就理解成啊这个什么叫做锁持。说是。啊。那么什么时候这个会进到锁池里边呢?
12:03
来。当我们的。这个线程在运行过程当中遇到了什么呀,这个关键字。一定是这个关键字啊叫什么。啊,遇到了这个关键字。当他遇到这个关键字之后呢。他会放弃占有的CPU。时间变。啊,他会干啥去锁池里边干啥呀,去找。找了一个共享对象的对象锁。啊,可以这样去理解。在这里找共享对象的对象锁。如果他没找到,他就一直在这等着。但是他肯定要在这等着的话,他肯定是放弃之前分配的时间片,比如说在原来在这分配了一分钟时间片,对吧,遇到星空night的八,他会放弃这个时间片啊,放弃时间片,放弃之前读的那一分钟啊,然后接下来进到锁舍里边找,找到共享对象之后呢,他马上会怎么着呢?哎,记住了,他马上。
13:09
会再次进入到就绪状态。啊,来这写上。线程进入锁池找线程进入锁池找共享对象的对象,锁的时候会释放之前占有的什么CPU时间片。当。有可能怎么着,找到了,有可能没找到。啊,没找到的时候。没找到则在什么呀?叫做锁池中等待。如果找到了。会进入什么呀,就绪状态,继续抢夺CPU时间片。
14:06
啊,CPU时间片在这有这么一段话啊,在这里找共享对应的对象锁,线程进入锁持找共享对象,对象锁的时候会释放之前占有CPU时间片,有可能找到也有可能。没有找到没有,没找到则在锁之中等待就行了啊,如果找到了会进入就绪状态,继续抢夺CPU时间片。啊,是这样的一个一个情况,各位啊,Synchronized只要是这个字很敏感很敏感啊,那这个共享对象很重要,如果你共享对象找不到,或者找的有问题,就会导致你的线程啊,还是非线程安全的,你排不了队啊,对吧,排不了队啊。好,这个大家要知道啊,大家知道这个大家理解吧。这个代码的执行原理是什么呀?是说我们县城怎么着?执行我们微方法的话,上来遇到了think关键字是不是,哎遇到关键字,遇到关键字之后呢。
15:06
他会找这个共享对应的对象锁吧,找到这个锁是不是就执行,找不到就是在外边等呗。对吧,所以你两个线程共享这个对象才可以啊。好,那么这边呢,咱们保存一下啊,保存一下这个锁持,这个要大家要了解一下,这不是一个状态,各位啊。嗯,你别把它归到五大状态里边,123455大状态啊,在面试官问的时候,你就说这五个状态就行了,下边这个锁持的话,它不属于一种状态啊,不属于一种状态。不过你也可以理解成遇到SYNCH是一种阻塞。明白吧,哎,你也可以理解成遇到S,它属于一种阻塞,属于一种阻塞,各位啊,阻塞。他有可能阻塞这个时间长有可能短,如果拿到锁的他就走,对吧,如果没拿到,他在外边阻塞了,一直等,所以它其实是属于一种阻塞的状态。
16:01
啊,阻塞状态中的一元吧,你可以这样去理解啊,我在这写一下,其实这个可以理解成是一种阻塞。这个啊,进入锁池可以理解为一种什么呀,阻塞状态。啊,阻塞状态。好关了啊。
我来说两句