一、原子性——锁
1、原子性就是提供了互斥访问,同一时刻只能有一个线程对它进行访问或者说操作.java中,除了jdk中的atomic包之外,还有锁。jjdk提供的锁主要有两种:
》synchronized 关键字: 依赖jvm. 在作用对象的作用范围内,可以保证在同一时刻只能有一个线程访问。注意synchronized的作用对象的作用范围内。
》Lock接口:依赖特殊的CPU指令,代码实现,比较有代表的实现类为ReentrantLock 类
2、原子性-synchronized
java的关键字,是一个同步锁,修饰的对象主要有四种:
》修饰代码块:大括号括起来的代码,作用于调用的对象,被修饰的代码块称为同步语句块;
》修饰方法;整个方法,作用于调用的对象,被修饰的方法称为同步方法;
》修饰静态方法;整个静态方法,作用于所有对象。注意这里的作用对象范围;
》修饰类:括号括起来的部分,作用于所有对象,注意这里的作用对象范围;
代码示例如下:
1)测试一;
注释:如上,使用了线程池,同一个方法调用了两次,从而模拟多线程并发,如果不使用线程池,那么调用两该方法,
这两个方法本身就是同步关系,无法实现测试效果。而线程池,第一个方法不执行完,第二个方法就可能被执行。
运行下结果:
然后是两次,每个连续的test1—0~9
2)测试二:
将上方的main() 中调用的test1()方法,都换成test2() 测试下,
效果同测试一。
3)测试三:
将上方的main方法中,再创建一个对象example2,如图:
注:test1() 方法添加了一个变量,用于方便查看测试效果,判断是哪个对象在运行:
运行结果
如上可以看出,两个对象执行时,每个对象自己按照从0到9的顺序执行,两个对象是互相交替,但两个对象互不影响,
4)测试4:
将上方的test2仿照test3 处理,然后运行,效果如下:
运行效果如下:
总结:不同对象之间互不影响;
如果一个方法中,整体都是同步代码块时,和同步方法效果是一样的。
注意,如果父类的方法用synchronized修饰时,子类是无法继承其synchronized的性质的,因为synchronized 不属于方法声明的一部分。如果子类也需要使用synchronized的特性,需要自身显示地添加该关键字。
5)测试5:如下开始模拟测试synchronized修饰静态方法:
6)测试6:synchronized修饰一个类
运行结果:
7)
8)总结:
原子性对比结果:
》synchronized :不可中断锁,适合竞争不激烈(竞争激烈时性能下降明显),可读性好;
》Lock :可中断锁(使用unlock可解锁),多样化同步,竞争激烈时能维持常态;
》Atomic :竞争激烈时能维持常态,比Lock性能好;但只能同步一个值。 最常用于做标志位。