concurrent-4-锁

来源:互联网 发布:硬盘坏了恢复数据 编辑:程序博客网 时间:2024/06/07 00:27

锁的设计

    1.减少锁持有时间        减少锁的持有时间有助于降低锁冲突的可能性,进而提升系统的并发能力。    2.减小锁粒度        缩小锁定对象的范围,从而减少锁冲突的可能性,进而提高系统的并发能力。    3.读写分离锁        在读多,写少的环境下用读写锁能大大减少线程等待时间。    4.锁粗化        在遇到一连串地对同一锁不断进行请求和释放的操作时,把所有的锁操作整合成对锁的一次请求,从而减少对锁的请求同步次数。

虚拟机对锁的优化

    1.锁偏向        如果一个线程获得了锁,那么锁就进入偏向模式,当这个线程再次请求锁时,无须再做任何同步操作。    2.轻量级锁    3.自旋锁    4.锁消除

无锁

    使用无锁的方式完全没有锁竞争带来的系统开销,也没有线程间频繁调度带来的开销,因此,它比基于锁的方式拥有更优越的性能

比较交换(CAS)

    它包含三个参数CAS(V,E,N) ,V表示要更新的变量,E表示预期值,N表示新值。仅当V值等于E值时,才会将V值设为N,如果V值和E值不同则说明有其它线程做了更新,则当前线程什么也不做。

AtomicInteger

        直接使用CAS操作的线程安全类型        AtomicLong,AtomicBoolean,AtomicReference类似;
//CAS 操作无须加锁,保证线程安全    private static AtomicInteger atomicInteger=new AtomicInteger();    private static CountDownLatch countDownLatch=new CountDownLatch(10);    public static void main(String[] args) {        ExecutorService executorService=Executors.newFixedThreadPool(10);        for (int i = 0 ; i < 10 ; i ++) {            executorService.submit(                    ()->{                        for(int k = 0 ; k < 10000 ; k ++) {                            atomicInteger.incrementAndGet();                        }                        countDownLatch.countDown();  //计数                    }            );        }        try {            countDownLatch.await();  //等待完成        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(atomicInteger);        //输出        //100000    }

AtomicStampedReference

        //加入时间戳的CAS对象引用操作,可能解决由于线程修改n次后值不变的bug问题
    private static AtomicStampedReference<Integer> reference=new AtomicStampedReference<>(19, 0);    public static void main(String[] args) {        for (int i=0; i < 3; i++) {            int stamp=reference.getStamp();            new Thread(                    () -> {                        while (true) {                            while (true) {                                Integer money=TestAtomicStamped.reference.getReference();                                if (money < 20) {                                    if (reference.compareAndSet(money, money + 20, stamp, stamp + 1)) {                                        System.out.println(" 充值20成功,余额 =" + reference.getReference());                                        break;                                    }                                } else {                                    System.out.println(" 余额大于20,无须充值");                                    break;                                }                            }                        }                    }            ).start();        }        for (int i=0; i < 3; i++) {            new Thread(                    () -> {                        while (true) {                            int stamp=reference.getStamp();                            Integer money=TestAtomicStamped.reference.getReference();                            if (money > 10) {                                if (reference.compareAndSet(money, money - 10, stamp, stamp + 1)) {                                    System.out.println(" 消费10,余额 = " + reference.getReference());                                    break;                                }                            } else {                                System.out.println(" 余额不足,请充值");                                break;                            }                        }                    }            ).start();        }    }    //输出    充值20成功,余额 =39    余额大于20,无须充值    余额大于20,无须充值    余额大于20,无须充值    消费10,余额 = 29    消费10,余额 = 19    消费10,余额 = 9    余额不足,请充值

死锁

    互相占用对方的请求的锁资源,造成线程blocking
private static  Object lock1 = new Object() ;    private  static  Object lock2 = new Object() ;    public static void main(String[] args) {        new Thread(                ()->{                    synchronized (lock1){                        try {                            Thread.sleep(2000);                            System.out.println(Thread.currentThread().getName() + "  lock1");                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                        synchronized (lock2) {                            System.out.println(Thread.currentThread().getName() + "  lock2");                        }                    }                }        ).start();        new Thread(                ()->{                    synchronized (lock2){                        try {                            Thread.sleep(2000);                            System.out.println(Thread.currentThread().getName() + "  lock2");                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                        synchronized (lock1) {                            System.out.println(Thread.currentThread().getName() + "  lock1");                        }                    }                }        ).start();    }    //输出    Thread-1  lock2    Thread-0  lock1
原创粉丝点击