使用synchronized、ReentrantLock与CAS自旋方式实现原子操作

原创 2018年04月17日 15:04:42

示例1:线程不安全的计数器

public class AddCountDemo {

    private int i = 0;

    public static void main(String[] args) {
        final AddCountDemo synchronizDemo = new AddCountDemo();
        for (int j = 0; j < 500; j++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronizDemo.addCount();
                }
            }).start();
        }
        // 使当前所有线程运行完成之后再运行以下代码
        while (Thread.activeCount() > 1) {
            Thread.yield();
        }
        System.out.println(synchronizDemo.i);
    }

    private void addCount() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.i++;
    }
}

示例2:使用synchronized实现线程安全的计数器

public class AddCountSynchronizDemo {
    private int i = 0;

    public static void main(String[] args) {
        final AddCountSynchronizDemo synchronizDemo = new AddCountSynchronizDemo();
        for (int j = 0; j < 500; j++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronizDemo.addCount();
                }
            }).start();
        }
        // 使当前所有线程运行完成之后再运行以下代码
        while (Thread.activeCount() > 1) {
            Thread.yield();
        }
        System.out.println(synchronizDemo.i);
    }

    private void addCount() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (this) {
            this.i++;
        }
    }
}

示例3:使用ReentrantLock方式实现线程安全的计数器

import java.util.concurrent.locks.ReentrantLock;

public class AddCountReentrantDemo {
    private int i = 0;

    private ReentrantLock reentrantLock = new ReentrantLock();

    public static void main(String[] args) {
        final AddCountReentrantDemo synchronizDemo = new AddCountReentrantDemo();
        for (int j = 0; j < 500; j++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronizDemo.addCount();
                }
            }).start();
        }
        // 使当前所有线程运行完成之后再运行以下代码
        while (Thread.activeCount() > 1) {
            Thread.yield();
        }
        System.out.println(synchronizDemo.i);
    }

    private void addCount() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        reentrantLock.lock();
        try {
            this.i++;
        } finally {
            reentrantLock.unlock();
        }
    }
}

示例4:使用CAS自旋方式实现线程安全的计数器

import java.util.concurrent.atomic.AtomicInteger;

public class AddCountCASDemo {

    private int i = 0;

    private AtomicInteger atomicInteger = new AtomicInteger(0);

    public static void main(String[] args) {
        final AddCountCASDemo synchronizDemo = new AddCountCASDemo();
        for (int j = 0; j < 500; j++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronizDemo.addCount();
                }
            }).start();
        }
        // 使当前所有线程运行完成之后再运行以下代码
        while (Thread.activeCount() > 1) {
            Thread.yield();
        }
        System.out.println(synchronizDemo.atomicInteger.get());
    }

    private void addCount() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //atomicInteger.compareAndSet()
        for (; ; ) {
            int i = atomicInteger.get();
            boolean result = atomicInteger.compareAndSet(i, ++i);
            if (result) {
                break;
            }
        }
    }
}
boolean result = atomicInteger.compareAndSet(i, ++i);
操作的时候会检查值有没有变化,如果没有发生变化则更新,而后返回true;如果操作值发生变化则返回false,程序在for循环中重新这些++i操作;

使用swing、三层架构实现学生管理系统

-
  • 1970年01月01日 08:00

CAS自旋锁

昨天写了篇关于AtomicInteger的博客,感觉觉还是不太完整,所以又把自旋锁的知识整理了一下。。。。。。。。。 什么是自旋锁        说道自旋锁就要从多线程下的锁机制说起,由于在多处理器系...
  • p10010
  • p10010
  • 2016-01-05 15:03:20
  • 1547

synchronized和lock(reentrantlock) 区别

1.某个线程在等待一个锁的控制权的这段时间需要中断 2.需要分开处理一些wait-notify,ReentrantLock里面的Condition应用,能够控制notify哪个线程 3.具有公平锁...
  • ningguixin
  • ningguixin
  • 2014-04-17 18:09:07
  • 6546

对于Synchronized、ReentrantLock、Atomic、CAS在并发下面的性能比较测试

对于Synchronized、ReentrantLock、Atomic、CAS在并发下面的性能比较,在JDK1.6和JDK1.8下面测试通过。 我们考虑一个最简单的并发场景,对对象自增字段在...
  • Meiyang1990
  • Meiyang1990
  • 2015-12-01 15:20:42
  • 929

Java三种锁机制初步分析总结(Synchronized Lock(ReentrantLock) Semaphore Atomic)

Java处理高并发,大数据,多线程,分布式这些都会产生一个严重的后果,如何保证线程安全和数据的一致性成为重中之重。为了实现这点就不得不使用到了锁机制,java提供了4种常见的锁机制,当然其中Synch...
  • qq838642798
  • qq838642798
  • 2017-01-13 00:30:28
  • 605

java的两种同步方式, Synchronized与ReentrantLock的区别

java在编写多线程程序时,为了保证线程安全,需要同步,经常用到两种同步方式就是Synchronized和重入锁ReentrantLock。 相似点: 这两种同步方式有很多相似之处,它们都是加锁方式同...
  • chenchaofuck1
  • chenchaofuck1
  • 2016-04-02 19:37:22
  • 10658

CAS自旋

CAS(Compare And Swap)比较并转换 该算法涉及三个数:内存值V,旧的预期值A,新的预期值B。当且仅当旧的预期值A和内存值V相同时,将内存值改为B,否则什么也不做。 ...
  • sinat_28028941
  • sinat_28028941
  • 2016-12-09 15:37:47
  • 809

synchronized和ReentrantLock区别浅析

一、什么是sychronized        sychronized是java中最基本同步互斥的手段,可以修饰代码块,方法,类.       在修饰代码块的时候需要一个reference对象作为锁的...
  • zmx729618
  • zmx729618
  • 2016-06-06 15:16:50
  • 2150

synchronized与ReentrantLock的介绍、使用、适合场景及比较

JDK 5.0为开发人员开发高性能的并发应用程序提供了一些很有效的新选择,目前存在两种锁机制:synchronized和Lock,Lock接口及其 实现类是JDK5增加的内容,ReentrantLoc...
  • Mr_Smile2014
  • Mr_Smile2014
  • 2016-08-08 15:29:15
  • 4009

ReenTrantLock可重入锁(和synchronized的区别)总结

ReenTrantLock可重入锁(和synchronized的区别)总结 可重入性: 从名字上理解,ReenTrantLock的字面意思就是再进入的锁,其实synchronized关键字所使用的...
  • qq838642798
  • qq838642798
  • 2017-03-23 11:31:29
  • 9814
收藏助手
不良信息举报
您举报文章:使用synchronized、ReentrantLock与CAS自旋方式实现原子操作
举报原因:
原因补充:

(最多只允许输入30个字)