一. 同步的原因
synchronized的代码块的封装作用,我们已经认识到了。但是它到底是怎么起到作用,现在来讨论一下。
这里面有一个对象,我们先简单地将它理解为标志位。这标志位怎么用的呢?
现在假想标志位有0和1,如果先来的默认值是1。这时,来了四个不同编号的线程,0~3。
0线程进来后,synchronized后面的标志位为1,(1代表着开着),进来后,就把1置为了0。标志位在0和1之间,进行了切换。
0和1可以理解为真假的假。当标志位为0的时候,后面的线程1,2,3读synchronized的时候,都进不来。
当0线程进来后,经过判断,开始执行语句,try里面有一个sleep语句。一旦0线程运行了sleep语句,cpu就开始切换到其他线程上了。
0线程释放了资格,释放了执行权。但是拿到执行权的其他线程,由于标志位为0,都进不来。这时,0线程醒了,执行完剩下的语句,就直接退出了。0线程刚推出的时候,就把标志位0变为了1。按照这个道理,1~3线程都是一样的过程。
这样一来,object就像锁一样。这是对象锁,或者同步锁。刚才说的标志位概念并不存在,真正的概念是锁。
为什么要放一个对象锁进来,后期要对同步中的线程进行监视,因为监视的方法都在锁上呢。
对象锁,同步地解决线程安全的原因。到这,同步的基本特点就介绍完了。
二. 同步的特点
线程里的问题很多,这里只是解决了部分问题。(同步应该说的是多个代码语句一起执行,比如这里的if判断,和try,以及输出语句)
0线程进到synchronized代码块中后,会一直持有cpu的执行权么?不会,如果一直持有,那么其他程序根本运行不了,比如说QQ,360....这就意味着,此时,cpu的执行权会切换到其他线程上,如1~3,但是无论这三个线程谁拿到执行权,都会被判断同步锁,判断完,进不去。相当于无效判断,所以效率会有点低。
这个效率低是可以在我们的承受范围之内的。