/**
* @Description:演示AtomicInteger的基本用法,对比非原子类的线程安全问题,使用原子类之后,不需要加锁,也可以保证线程安全。
*/
public class AtomicIntegerDemo1 implements Runnable{
private static final AtomicInteger atomicInteger = new AtomicInteger();
public void incrementAtomic(){
atomicInteger.getAndIncrement();
}
//普通变量
private static volatile int basicCount =0;
public void incrementBasic(){
basicCount++;
}
public static void main(String[] args) throws InterruptedException {
AtomicIntegerDemo1 r = new AtomicIntegerDemo1();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("原子类的结果是:"+atomicInteger.get());
//体现了普通变量在多线程情况下,无法保证线程安全
System.out.println("普通变量的结果是:"+basicCount);
}
@Override
public void run(){
for (int i = 10000; i > 0; i--) {
incrementAtomic();
incrementBasic();
}
}
}
在给普通变量的increment()加上synchronized也可以实现线程安全,但是效率较为低下。
public synchronized void incrementBasic(){
basicCount++;
}
/**
* @Classname AtomicArrayDemo1
* @Description 演示原子数组的使用方法
* @Date 2021/2/16 9:09
* @Created by YoungLiu
*/
public class AtomicArrayDemo1 {
public static void main(String[] args) throws InterruptedException {
AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(1000);
Increment increment = new Increment(atomicIntegerArray);
Decrementer decrementer = new Decrementer(atomicIntegerArray);
Thread[] threadsIncrementer = new Thread[100];
Thread[] threadsDecrementer = new Thread[100];
for (int i = 0; i < 100; i++) {
threadsDecrementer[i]=new Thread(decrementer);
threadsDecrementer[i].start();
threadsIncrementer[i]=new Thread(increment);
threadsIncrementer[i].start();
}
for (int i = 0; i < 100; i++) {
threadsDecrementer[i].join();
threadsIncrementer[i].join();
}
for(int i =0;i<atomicIntegerArray.length();i++){
if(atomicIntegerArray.get(i)!=0){
System.out.println("发现了非0值,错误的位置 "+i);
}
System.out.println(atomicIntegerArray.get(i));
}
System.out.println("运行结束");
}
}
class Decrementer implements Runnable{
private AtomicIntegerArray array;
public Decrementer(AtomicIntegerArray array){
this.array=array;
}
@Override
public void run() {
for(int i =0;i<array.length();++i){
array.getAndDecrement(i);
}
}
}
class Increment implements Runnable{
private AtomicIntegerArray array;
public Increment( AtomicIntegerArray array){
this.array=array;
}
@Override
public void run() {
for(int i=0;i<array.length();++i){
array.getAndIncrement(i);
}
}
}
以spinLock的代码为示例
public class SpinLock {
private AtomicReference<Thread> sign= new AtomicReference<>();
public void lock(){
//得到当前线程的引用
Thread current = Thread.currentThread();
while(!sign.compareAndSet(null,current)){
System.out.println(Thread.currentThread().getName()+"本次尝试获取自旋锁失败");
}
}
public void unlock(){
Thread current = Thread.currentThread();
sign.compareAndSet(current,null);
}
public static void main(String[] args) {
SpinLock spinLock = new SpinLock();
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "开始尝试获取自旋锁");
spinLock.lock();
System.out.println(Thread.currentThread().getName() + "获取到了自旋锁");
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
spinLock.unlock();
System.out.println(Thread.currentThread().getName()+"释放了自旋锁");
}
}
};
Thread t0 = new Thread(runnable);
Thread t1 = new Thread(runnable);
t0.start();
t1.start();
}
}
/**
* @Classnam AtomicIntegerFieldUpdaterDemo
* @Description:演示AtomicIntegerFieldUpdater用法
* @Date 2021/2/16 9:31
* @Created by YoungLiu
*/
public class AtomicIntegerFieldUpdaterDemo implements Runnable {
static Candidate tom;
static Candidate peter;
public static AtomicIntegerFieldUpdater<Candidate> scoreUpdater =
AtomicIntegerFieldUpdater.newUpdater(Candidate.class, "score");
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
peter.score++;
//实现对普通变量的原子操作
scoreUpdater.getAndIncrement(tom);
}
}
public static class Candidate {
volatile int score;
}
public static void main(String[] args) throws InterruptedException {
AtomicIntegerFieldUpdaterDemo r = new AtomicIntegerFieldUpdaterDemo();
tom = new Candidate();
peter = new Candidate();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("upgrading tom:" + tom.score);
System.out.println("normal peter:" + peter.score);
}
}
从程序输出结果可以看到,升级后的变量,实现了原子性操作。
1.可见范围 — 不能操作private的变量
2. 不支持static变量
/**
* @Classname AtomicLongDemo
* @Description 演示高并发场景下,LongAdder比AtomicLong性能高
* @Date 2021/2/16 10:09
* @Created by YoungLiu
*/
public class AtomicLongDemo {
public static void main(String[] args) throws InterruptedException {
AtomicLong counter = new AtomicLong(0);
ExecutorService service = Executors.newFixedThreadPool(16);
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
service.submit(new Task(counter));
}
service.shutdown();
while(!service.isTerminated()){
//为了计算执行任务的耗时;
//此处等待所有任务执行完毕后才往下执行。
}
long end = System.currentTimeMillis();
System.out.println(counter.get());
System.out.println("AtomicLong耗时:"+(end-start));
}
private static class Task implements Runnable{
private AtomicLong counter;
public Task(AtomicLong counter){
this.counter=counter;
}
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
counter.incrementAndGet();
}
}
}
}
**
* @Classname LongAdderDemo
* @Description TODO
* @Date 2021/2/16 10:15
* @Created by YoungLiu
*/
public class LongAdderDemo {
public static void main(String[] args) throws InterruptedException {
LongAdder counter = new LongAdder();
ExecutorService service = Executors.newFixedThreadPool(20);
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
service.submit(new LongAdderDemo.Task(counter));
}
service.shutdown();
while(!service.isTerminated()){
}
long end = System.currentTimeMillis();
System.out.println(counter.sum());
System.out.println("longAdder耗时:"+(end-start));
}
private static class Task implements Runnable{
private LongAdder counter;
public Task(LongAdder counter){
this.counter=counter;
}
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
counter.increment();
}
}
}
}
对比两个程序的输出,可以看出在高并发情况下,LongAdder的性能比AtomicLong要高。
由于CPU有不同的core,每个core做完一次操作后,其他的core都要刷新一次它的缓存,这会造成资源浪费。
/**
* @Classname LongAccmulatorDemo
* @Description 演示LongAccumulator用法
* @Date 2021/2/16 11:18
* @Created by YoungLiu
*/
public class LongAccmulatorDemo {
public static void main(String[] args) {
//最开始这个0,是赋给x的
LongAccumulator accumulator = new LongAccumulator((x, y) -> x + y, 0);
ExecutorService service = Executors.newFixedThreadPool(8);
IntStream.range(1,10).forEach(i-> service.submit(()->accumulator.accumulate(i)));
accumulator.accumulate(1);
service.shutdown();
while(!service.isTerminated()){
}
System.out.println(accumulator.getThenReset());
}
}