多线程与并发编程(三)

  • 递增问题中的atomic,sync,LongAdder

    • 为什么atomic比sync快,乐观锁与悲观锁的效率区别
    • 为什么LongAdder比上面都要快?用的分段锁并且底层也是乐观锁cas
      • 内部像一个分段锁,举个例子,1000个请求,他分成了4段,都是零,每一段加250个请求,最后再把四个地方全都加起来作为结果
  • ReentrantLock可重入锁

    • 其实synchronized也是可重入锁,这意味着两者可以在一个sync同步方法中调用另一个sync同步方法

    • lock的锁定和开锁都是人为确定的,所以简单使用的时候建议包裹try catch finally保证lock一定要解锁

      Lock lock =new ReentrantLock();
      try{
          lock.lock();
      }catch(Exception e){
          e.printStackTrace();
      }finally{
          lock.unlock();
      }
      
    • boolean locked=Lock.tryLock(time,TimeUnit.SECONDS)

      可以在一段时间内尝试获取锁

    • Lock.lockInterruptibly()

      不是Lock.lock()这种获取不到锁不可打断的锁,而是一种可以被lock.interrupt()打断的锁

    • 公平锁,来了就在队列里乖乖排队

      Lock lock =new ReentrantLock(true);
      
  • ReentrantLock vs synchronized

    cas vs sync

    公平和非公平vs非公平

    tryLock() lockInterruptibly() vs不可尝试获取锁,不可中断

  • CountDownLatch,Latch门栓

    • Thread []threads=new Threads[100];
      CountDownLatch latch=new CountDownLatch(threads.length());
      
      for(int i=0;i<threads.length;i++){
          threads[i]=new Thread(()->{
              sout(i);
              latch.countDown();
          });
      }
      
      for(itn i=0;i<threads.length;i++){
          threads[i].start();
      }
      
      try{
          //拴住
          latch.await();
          //都做完的之后的代码
          sout("finish");
      }catch(InterruptedException e){
          e.printStackTrace();
      }
      
    • 如果用join实现?

          Thread t1 = new Thread(new Print("A"));
          Thread t2 = new Thread(new Print("B"));
          Thread t3 = new Thread(new Print("C"));
      
          t1.start();
          t2.start();
          t3.start();
          try {
              t1.join();
              t2.join();
              t3.join();
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      
  • CyclicBarrier循环屏障,挡住一直到指定数值,再继续执行代码

    • ClclicBarrier barrier =new CyclicBarrier(20,new Runnable(){
          public void run(){sout("发车");}
      });
      for(int i=0;i<100;i++){
          new Thread(()->{
              try{
                  barrier.await();
              }catch(...){
                  ...
              }
          }).start();
      }
      
  • Phaser不同阶段执行不同操作(面试几乎没见过,了解就好几乎不用-遗传算法?)

    • 他有点像CyclicBarrier,但是是一个栅栏,一个栅栏的用

    • 比如把结婚分为,arrive,eat,leave,hug四个阶段,那么必须前一个阶段的所有线程都到了,才进入下一个阶段,比如必须所有人都arrive才能eat全eat完才能走,但是最后hug只能新娘新郎

    • //自定义继承类,重写onAdvance方法
      static class MarriagePhaser extends Phaser{
          //onAdvance会在栅栏被推到时自动调用,从0开始
          @Override
          prptected boolean onAdvance(int phase,int registeredParties){
              switch(phase){
                  case 0:
                      sout("arrive finish");
                      return false;
                  case 1:
                      sout("eat finish");
                      return false;
                  case 2:
                      sout("leave finish");
                      return false;
                  case 3:
                      sout("hug");
                      return true;
                  default:
                      return true;
              }
          }
      }
      MarriagePhaser phaser=new MarriagePhaser
      public void arrive(){
          sout("arrive");
          phaser.arriveAndAwaitAdcance();
      }
      public void eat(){
          sout("eat");
          phaser.arriveAndAwaitAdcance();
      }
      public void leave(){
          sout("leave");
          phaser.arriveAndAwaitAdcance();
      }
      public void hug(){
          if(name.equals("新郎")||name.equals("新娘")){
              phaser.arriveAndAwaitAdcance();
          }else{
              //其他人不能hug,deregister不让他注册
              phaser.arriveAndDeregister();
          }
      }
      
      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();
      }
      
  • ReadWriteLock读写锁

    • 为了让多个读线程都可以直接进入,而不用再去等待

      底层使用了两把锁
      static ReadWriteLock readWriteLock =new ReentrantReadWriteLock();
      static Lock readLock=readWriteLock.readLock();//共享锁
      static Lock writeLock=readWriteLock.writeLock();//排他锁
      
      read()的时候,传readLock
      write()的时候,传writeLock
      
  • Semaphore 信号灯-限流-分批

    //permit表示最多同时执行的线程数,fair表示是否公平
    Semaphore s=new Semaphore(permits,fair);
    
    new Thread(()->{
      try{
          //阻塞方法,尝试获取锁,如果拿不到会阻塞,拿到会减一
          s.acquire();
          sout("doing 1");
          s.release();
      }catch(InterruptException e){
          e.printStackTrace();
      }
    }).start();
    new Thread(()->{
      try{
          //阻塞方法,如果拿不到会阻塞拿到会减一
          s.acquire();
          sout("doing 2");
          s.release();
      }catch(InterruptException e){
          e.printStackTrace();
      }
    }).start();
    
  • newFixedThreadPool与Semaphore
    • 两者挺像的,线程池表示同时最多跑Fixed的线程数,Semaphore表示100个,或者更多的线程只能同时跑permits个,Semaphore是做同步的!
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容