concurrent-4-锁

锁的设计
    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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值