多线程与高并发3-atomic分段锁+同步锁

LongAdder

juc.atomic包下,在很高并发情况下效率比AtomicLong效率要高

原理:在底层是一个分段锁的设计,分成一个线程数组,将线程分别锁定在不同元素中,算出结果后加到一起。分段锁也是CAS。

效率比较:
sync<atomic,无锁乐观锁(sync在小数量小并发未必效率低,锁升级)
atomic<LongAdder,分段锁

ReetrantLock(底层为CAS)

可重入锁:在同一线程内,可反复获得锁
(sync必是可重入的,如果不能重入,子类无法调用父类锁)

加锁解锁

Lock lock = new ReetrantLock();
lock.lock();//加锁
lock.unlock();//解锁(finally)

尝试获得锁

//5秒钟之内获得锁,未获得取消操作
//返回boo值,如果获取到锁返回true
boolean boo = lock.tryLock(5,TimeUnit.SECONDS);

可打断锁

lock.lockInterruptibly();//可以对interrupt进行响应

公平锁

Lock lock = new ReetrantLock(true);//设置为公平锁

CountDownLatch

倒数门闩

CountDownLatch cdl = new CountDownLatch(100);//计数100次
cdl.countDown();//在线程执行完毕后,进行倒数计数-1
cdl.await();//等待,在执行完100次后归零,打开门闩

CyclicBarrier

循环栅栏(限流)

1、复杂操作:
1.数据库
2.网络
3.文件

2、并发执行

CyclicBarrier cb = new CyclicBarrier(20,() -> System.out.println("20已满,发车!") );
cb.await();//等待

Phaser

阶段,栅栏组。可以控制栅栏个数,和栅栏等待线程等待数量

static class MyPhaser extends Phaser {
        @Override
        protected boolean onAdvance(int phase, int registeredParties) {

            switch (phase) {
                case 0:
                    System.out.println("第一个方法执行!" + registeredParties);
                    System.out.println();
                    return false;
                case 1:
                    System.out.println("第二个方法执行!" + registeredParties);
                    System.out.println();
                    return false;
                case 2:
                    System.out.println("第三个方法执行!" + registeredParties);
                    System.out.println();
                    return false;
                case 3:
                    System.out.println("第四个方法执行!" + registeredParties);
                    return true;//返回true所有线程结束
                default:
                    return true;
            }
        }
    }
     public static void main(String[] args) {

        phaser.bulkRegister(7);//设置栅栏线程个数

        for(int i=0; i<5; i++) {

            new Thread(new Person("p" + i)).start();
        }

        new Thread(new Person("新郎")).start();
        new Thread(new Person("新娘")).start();

    }
    static class Person implements Runnable {
        String name;

        public Person(String name) {
            this.name = name;
        }

        public void arrive() {
          	System.out.printf(“第一个”);
            phaser.arriveAndAwaitAdvance();//到达等待
        }

        public void eat() {
           System.out.printf(“第二个”);
            phaser.arriveAndAwaitAdvance();
        }

        public void leave() {
           System.out.printf(“第三个”);
           phaser.arriveAndAwaitAdvance();
        }

        private void hug() {
            if(name.equals("1") || name.equals("2")) {
                System.out.printf(“第四个”);
                phaser.arriveAndAwaitAdvance();
            } else {
                phaser.arriveAndDeregister();//到达并取消注册
                //phaser.register()
            }
        }

        @Override
        public void run() {
        	//按序执行
            arrive();


            eat();


            leave();


            hug();

        }
    }

按照栅栏顺序执行, phaser.arriveAndAwaitAdvance();栅栏等待

ReadWriteLock

读写锁
读锁:共享锁
写锁:排他锁(互斥锁)

ReadWriteLock rwl = new ReentrantReadWriteLock();
Lock readL = rwl.readLock();
Lock writeL = rwl.writeLock();

通过读锁共享,写锁排他,读必须上锁防止写操作进入

Semaphore

信号量(限流,卖票)

//允许一个线程同时执行,第二个参数可传true,公平锁属性
Semaphore s = new Semaphore(1);
s.acquire();//如果信号量不为0,取得信号量锁,该信号量由1变为0
s.release();//释放信号量,该信号量由0恢复为1

Exchanger

交换两个线程的数据。
Exchanger容器会保存数据,当第一个线程调用exchange时,该线程阻塞,将值放到容器中。第二个线程调用exchange时,将该值放到容器中。两个值交换后。继续执行其他线程

Exchanger<String> ex = new Exchanger<>();
String result = ex.exchange(result);//两个线程进行调用,互换数据

LockSupport

LockSupport.park();//线程阻塞
LockSupport.unpark();//线程继续执行,unpack可以在park之前调用
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值