多线程问题volatile Synchronise Lock and AtomicReference

以前用到的关于锁和线程安全注意的地方比较少,最近项目出现一些公用内容需保证线程安全所以采用AtomicReference 和concurrentMap,

顺便再梳理了下线程安全的内容:

从性能上来说AtomicReference比synochronizd 和 Lock要好得多。

下面来看下一些实现:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockTask implements Runnable {
    private int lockVariable;
    private Lock lock;

    public LockTask() {
        this.lockVariable = 0;
        this.lock = new ReentrantLock();
    }

    @Override
    public void run() {
        for (int i = 0; i < 1000000000; i++) {
            lock.lock();
            lockVariable = i;
            lock.unlock();
        }
    }
}

  

public class SecuritySingleton {
    private static SecuritySingleton securitySingleton;

    private SecuritySingleton(){};

    static synchronized SecuritySingleton getInstance(){
        if(securitySingleton==null){
            securitySingleton = new SecuritySingleton();
        }
        return securitySingleton;
    }

}

 

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicTask implements Runnable {
    private final AtomicInteger variableInt;

    public AtomicTask() {
        this.variableInt = new AtomicInteger(0);
    }

    @Override
    public void run() {
        for (int i = 0; i < 1000000000; i++) {
            variableInt.set(1);
        }
    }
}

  

 

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;

public class AtomicService {
    private final AtomicReference<Map<String, String>> areaMapping = new AtomicReference<>();

    private AtomicService() {
        this.areaMapping.set(new ConcurrentHashMap());
    }

    public void addValue(String key, String value) {
        areaMapping.get().put(key, value);
    }

    public String getValue(String key) {
        return areaMapping.get().get(key);
    }
}

  

 

摘抄自博客:https://www.cnblogs.com/caiba/p/10616615.html

synochronizd和volatile关键字区别:
1. volatile关键字解决的是变量在多个线程之间的可见性;而sychronized关键字解决的是多个线程之间访问共享资源的同步性。
2. volatile只能用于修饰变量,而synchronized可以修饰方法,以及代码块。(volatile是线程同步的轻量级实现,所以volatile性能比synchronized要好,并且随着JDK新版本的发布,sychronized关键字在执行上得到很大的提升,在开发中使用synchronized关键字的比率还是比较大)
3. 多线程访问volatile不会发生阻塞,而sychronized会出现阻塞。
4. volatile能保证变量在多个线程之间的可见性,但不能保证原子性;而sychronized可以保证原子性,也可以间接保证可见性,因为它会将私有内存和公有内存中的数据做同步。

线程安全包含原子性和可见性两个方面。
对于用volatile修饰的变量,JVM虚拟机只是保证从主内存加载到线程工作内存的值是最新的。
一句话说明volatile的作用:实现变量在多个线程之间的可见性。

synchronized和lock区别
1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;

2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;

3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;

4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。

5)Lock可以提高多个线程进行读操作的效率(读写锁)。

  在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。

posted on 2020-12-26 21:54  涤生-三省吾身  阅读(157)  评论(0编辑  收藏  举报

导航