第三讲-互斥锁(上),解决原子性问题
引出问题:
导致原子性原因是线程切换,禁止线程切换,这个问题不就解决了吗?
单核CPU,禁止线程切换,可以保证线程对共享变量的修改是互斥的;
多核CPU,禁止线程切换,无法保证线程对共享变量的修改是互斥的;
合理方案:
同一时刻只有一个线程执行,称为互斥;如果能保证对共享变量的修改是互斥的,无论是单核CPU,还是多核CPU,
都能保证原子性;
锁模型:
java中锁技术:synchronzied
1)对应锁模型中加锁的lock() 和解锁的unlock()操作,java编译器会在synchronized修饰的方法或代码块前后自动加上;
2) 当修饰静态方法时,锁定的是当前类的Class对象;当修饰非静态方法时,锁定的是当前实例对象this;
案例分析:
背景:
管程中锁的规则:对一个锁的解锁 Happens-Before后续对这个锁的加锁;
传递性: A Happens-Before B,B Happens-Before C,则A Happens-Before C;
分析:
1)对于add()方法,synchronized可以保证其原子性,同一时刻只有一个线程能进入add方法;
2)可见性问题,根据Happens-Before中管程中锁的规则、传递性原则,可以知道,前一个线程在临界区修改的
变量对后续进入临界区的线程是可见的;
因此,如果有100个线程操作add()方法,最终的结果一定是x=100;
3)线程要进入add() 方法、add()方法,用到的是同一把锁(this锁),符合管程中锁的规则,传递性原则,所以也
不存在可见性问题;