- 线程同步的概念:
线程同步的根本目的就是为了保证线程对同步代码或者同步函数one by one的运行,最终目的是为了保证数据的一致性。
每一个对象都可以充当这样的锁,因为任意一个对象都有一个标志位,有1和0两种状态
*当程序执行到synchronized代码块的时候线程会检查对象的标志位是1还是0
*如果是1则执行程序,同时将对象的标志位设置为0,其他线程执行到synchronized代码块时一看对象标志位为0
*则线程会阻塞,一直等到对象的标志位为1再执行下面的程序如上的过程很像火车上的厕所,在上厕所之前,查看门上的标志:有人还是空闲;如果有人,则等待,如果没人,则进去使用;进到厕所后,把门插好,即更新了门上的标志,把空闲变为有人;这个过程中,如果有其他要使用厕所,则会在门口等待;使用完毕后,把标志改为空闲,离开厕所;其他人按照先来后到的顺序得到使用厕所的机会。
我们也可以把对象标志位看成一个监视器,当一个线程执行到synchronized代码块的时候会检查监视器的状态,一个刚执行完synchronized代码块的线程也可以再次检查监视器并执行synchronized代码块;
多个线程要实现同步,必须使用相同的监视器对象;如果多个线程使用的不是同一个监视器对象则达不到同步的效果
- 线程同步的不仅仅是一个代码块
同步过程需要注意的一点是:同步的不仅仅是同一个代码块,也可以是多个代码块进行同步,例如一个方法内的多个同步函数,他们之间是同步的,即在任意一个时刻,只有一个线程访问一个方法,其他的方法也是不允许访问的。例如集合的put和get操作,既不允许多个线程同时put或者同时get,也不允许同时有线程put和get。
- 对sleep 和 yield方法不释放对象锁的理解
线程sleep和yield的过程中是不释放对象锁的,因此同时对该锁同步的其他线程没有机会执行。为什么这样呢,我的理解是:既然线程同步的根本目的就是为了保证线程对同步代码或者同步函数one by one的运行,最终目的是为了保证数据的一致性。sleep和yield的调用可能出现在同步代码中,如果释放了锁,允许其他同步的线程执行,这样就打破了让同步线程one-by-one执行的目的,数据的一致性被破坏。