Java线程安全解决方案(synchronized,ReentrantLock,Atomic使用场景描述)dockers-Cgroup资源分配配置与安全

因此读取频繁使用乐观锁,写入频繁使用悲观锁。php

且这个锁能够定义成公平锁还能够定义成非公平锁。css

ReentrantLock使用场景:

ReentrantLock提供了多样化的同步,好比有时间限制的同步,能够被Interrupt的同步(synchronized的同步是不能Interrupt的)等 。html

/** * 线程安全的hashMap */ private static ConcurrentHashMap<string,string> hashMap = new ConcurrentHashMap<>(); public static void put(String key,String value){ hashMap.put(key,value); } public static String get(String key{ return hashMap.get(key); }

ConcurrentHashMap内部的实现是CAS的乐观锁,当锁没法取得会开始自旋,直到下一次取得锁。缘由在于,编译程序一般会尽量的进行优化synchronized,另外可读性很是好,无论用没用过5.0多线程包的程序员都能理解。前端

/** * synchronized用id */ private static volatile Long syncId=0L; /** * synchronized方式获取id 同步方法 * @return */ public static synchronized Long getSyncId1(){ syncId++; return syncId; } /** * synchronized方式获取id 同步代码块 * @return */ public static Long getSyncId2(){ synchronized (syncId){ syncId++; return syncId; } }

代码可读性强,毕竟是java的关键字,执行优先级高 。经常使用有java关键synchronized、由于他不能在多个Atomic之间同步。可是当同步很是激烈的时候,synchronized的性能一会儿能降低好几十倍。vue

Atomic或者Concurrent使用场景:

和上面的相似,不激烈状况下,性能比synchronized略逊,而激烈的时候,也能维持常态。java

/**     * ReentrantLock用id     */    private static volatile Long lockId=0L;    /**     * ReentrantLock公平锁     */    private static final ReentrantLock reentrantLock = new ReentrantLock(true);    /**     *  ReentrantLock方式获取id     * @return     */    public static Long getLockId(){        reentrantLock.lock();        try {            lockId++;            return lockId;        }catch (Exception e){            e.printStackTrace();            return getLockId();        }finally {            reentrantLock.unlock();        }    }

我这里以公平锁做为演示对象。可重入锁ReentrantLock,还有并发包下的Atomic或者Concurrent的安全类型。
在资源竞争激烈可使用其余方式来加锁 。在资源竞争不激烈的情形下,性能稍微比synchronized差点点。可是其有一个缺点,就是只能同步一个值,一段代码中只能出现一个Atomic的变量,多于一个同步无效。这时候就须要解决线程安全的问题,这时候就可使用java当中的锁机制。node

/**     * Atomic用id     */    private static volatile AtomicLong atomicId=new AtomicLong(0L);    /**     * Atomic方式获取id     * @return     */    public static Long getAtomicId(){        return  atomicId.addAndGet(1);    }

对于其余类型的好比和Map和Set可使用用并发包下的ConcurrentHashMap和ConcurrentHashSet等线程安全的数据类型。能够多对方法进行加锁(同步方法),也能够对对象进行加锁(同步代码快)。而ReentrantLock还能保证正常的性能。激烈的时候,Atomic的性能会优于ReentrantLock一倍左右。可是由于ReentrantLock是悲观锁,加锁时会对资源进行加锁,当读取频繁时性能会不如CAS的乐观锁。当从轻量级锁到偏向锁,再到一个重量级锁。python

线程安全解决方案

synchronized,ReentrantLock,Atomic 使用场景描述

在实际开发过程当中若是服务量,请求频繁,就会常常遇见并发,这时候不作处理就会出现不少非法数据。性能会大大的下降。mysql

synchronized使用场景:

在资源竞争不是很激烈的状况下,偶尔出现并发,须要同步的情形下,synchronized是很合适的。react

ReentrantLock还能够查看锁的状态, 锁是否被锁上了.
能够查看当前有多少线程再等待锁。
可是还有一个问题,当前资源竞争激烈时,对于部分线程迟迟获取不到锁,这时候会出现一个锁升级的过程,且锁升级的过程是不可逆的。synchronized关键字一放,就解决线程安全的问题。

 

相关文章

相关文章
相关标签/搜索