java多线程新特性

  1. Java的线程池分好多种:固定尺寸的线程池、单任务线程池、 可变尺寸连接池、延迟连接池、单任务延迟连接池、自定义线程池

  2. 固定大小的线程池

    方法说明
    ExecutorService pool =Executors.newFixedThreadPool(2);指定线程池并发上限
    Thread thread = new Thread(() -> {
                System.out.println(123);
            });
    ExecutorService threadPool = Executors.newFixedThreadPool(10);
    threadPool.execute(thread);
    threadPool.shutdown();
    
    1. 线程池中,线程用完后是要全部回收的,再用要重新分配。
    2. 完成了对线程对象的重用,避免了重复创建线程对象造成的资源浪费
    3. 关闭线程池后,不可以再添加新的线程到池当中,再加就会报错
  3. 单任务线程池

    方法说明
    ExecutorService pool=Executors.newSingleThreadExecutor();线程池并发上限为1
  4. 可变尺寸的线程池

    方法说明
    ExecutorService pool=Executors.newCachedThreadPool();并发全部线程
  5. 延迟线程池

    方法说明
    ScheduledExecutorService pool=Executors.newScheduledThreadPool(2);延迟执行线程,可指定并发上限
    1. 当当前线程池资源****被占用****,延迟线程顺延排队执行
    2. 如果资源没有被占用,则加入到批次中
    3. 延迟线程一样需要竞争资源
  6. 单任务延迟线程池

    方法说明
    ScheduledExecutorService pool=Executors.newSingleThreadScheduledExecutor();线程池并发上限为1,可延迟执行
  7. 自定义线程池

    方法说明
    BlockingQueue bqueue=new ArrayBlockingQueue(2);线程等待队列
    ThreadPoolExecutor pool = new ThreadPoolExecutor(2,2,0,TimeUnit.MILLISECONDS,bqueue);自定义线程池
    参数说明参数说明
    corePoolSize核心线程池大小unit时间单位
    maximumPoolSize最大线程池大小workQueue线程等待队列
    keepAliveTime线程最大空闲时间

    三者之间的关系:

    1. 如果没有空闲的线程执行该任务且当前运行的线程数少于corePoolSize,则添加新的线程执行该任务。
    2. 如果没有空闲的线程执行该任务且当前的线程数等于corePoolSize同时workQueue未满,则将任务入workQueue,而不添加新的线程。
    3. 如果没有空闲的线程执行该任务且workQueue已满同时池中的线程数小于maximumPoolSize,则创建新的线程执行任务。
    4. 如果没有空闲的线程执行该任务且workQueue已满同时池中的线程数等于maximumPoolSize,则根据构造函数中的handler指定的策略来拒绝新的任务。
  8. 有返回值的线程

    接口说明
    Callable可返回值的任务必须实现Callable接口
    1. 实现了Callable接口
    2. 任何线程必须join到Callable之后才会执行
    3. 应用场景:当当前线程需要前一个线程的执行结果,才能继续执行时,需要get()结果
    4. 如果不需要返回值,则其和普通线程没有任何区别
  9. 线程池-锁

    接口说明
    Lock lock=new ReentrantLock();锁对象,可以便捷的获取锁或者释放锁
    1. 读写锁:

      1. 场景:对共享资源有读和写的操作,且写操作没有读操作那么频繁。在没有写操作的时候,多个线程同时读一个资源没有任何问题,所以应该允许多个线程同时读取共享资源;但是如果一个线程想去写这些共享资源,就不应该允许其他线程对该资源进行读和写的操作了。
      2. 三种特性:
        1. 公平选择性:支持非公平(默认)和公平的锁获取方式,吞吐量还是非公平优于公平。
        2. 重进入:读锁和写锁都支持线程重进入。
        3. 锁降级:遵循获取写锁、获取读锁再释放写锁的次序,写锁能够降级成为读锁。
      接口说明
      ReadWriteLock lock=new ReentrantReadWriteLock(false);可针对读或者写操作锁,提高效率。 参数true:公平锁(公平锁的效率没非公平性高),线程获取锁的顺序和调用lock的顺序一样,不会存在饥饿的线程 false:非公平锁(默认),线程获取锁的顺序和调用lock的顺序无关,有可能存在饥饿线程

      结论:一个线程要想同时持有写锁和读锁,必须先获取写锁再获取读锁;写锁可以“降级”为读锁;读锁不能“升级”为写锁。

  10. 线程池-信号量

    接口说明
    Semaphore sp = new Semaphore(50);当信号量满时,线程进入等待
    Semaphore semaphore = new Semaphore(10);
    semaphore.acquire(1);
    semaphore.release(1);
    
    参数说明
    acquire(10)增加指定信号量
    release(10)释放指定信号量
  11. 线程池-阻塞队列:

    接口说明
    BlockingQueue bqueue = new ArrayBlockingQueue(20);一个指定长度的队列,如果队列满了,添加新元素的操作会被阻塞等待,直到有空位为止
    参数说明
    boolean add(E e)将给定元素设置到队列中,如果设置成功返回true, 否则返回false。如果是往限定了长度的队列中设置值,推荐使用offer()方法
    boolean offer(E e)将给定的元素设置到队列中,如果设置成功返回true, 否则返回false. e的值不能为空,否则抛出空指针异常。
    void put(E e)将元素设置到队列中,如果队列中没有多余的空间,该方法会一直阻塞,直到队列中有多余的空间。
    boolean offer(E e, long timeout, TimeUnit unit)将给定元素在给定的时间内设置到队列中,如果设置成功返回true, 否则返回false。
    E take()从队列中获取值,如果队列中没有值,线程会一直阻塞,直到队列中有值,并且该方法取得了该值
    E poll(long timeout, TimeUnit unit)在给定的时间里,从队列中获取值,时间到了直接调用普通的poll方法,为null则直接返回null
    int remainingCapacity()获取队列中剩余的空间
    boolean remove(Object o)从队列中移除指定的值
    boolean contains(Object o)判断队列中是否拥有该值
    int drainTo(Collection<? super E> c)将队列中值,全部移除,并发设置到给定的集合中
    int drainTo(Collection<? super E> c, int maxElements)指定最多数量限制将队列中值,全部移除,并发设置到给定的集合中
  12. 线程池-阻塞栈:

    接口说明
    BlockingDeque bDeque = new LinkedBlockingDeque(20);是双向链表实现的双向并发阻塞队列。
    参数说明
    boolean addFirst(E e)如果立即可行且不违反容量限制,则将指定的元素插入此双端队列的开头
    boolean addLast(E e)如果立即可行且不违反容量限制,则将指定的元素插入此双端队列的末尾
    E getFirst()获取,但不移除此双端队列的第一个元素
    E getLast()获取,但不移除此双端队列的最后一个元素
    boolean offerFirst(E e)如果立即可行且不违反容量限制,则将指定的元素插入此双端队列的开头,并在成功时返回 true;如果当前没有空间可用,则返回 false
    boolean offerFirst(E e, long timeout, TimeUnit unit)将指定的元素插入此双端队列的开头,必要时将在指定的等待时间内等待可用空间,返回值为Boolean
    boolean offerLast(E e)如果立即可行且不违反容量限制,则将指定的元素插入此双端队列的末尾,并在成功时返回 true;如果当前没有空间可用,则返回 false
    boolean offerLast(E e, long timeout, TimeUnit unit)将指定的元素插入此双端队列的末尾,必要时将在指定的等待时间内等待可用空间,返回值为Boolean
    参数说明
    E pollFirst()获取并移除此双端队列的第一个元素;如果此双端队列为空,则返回 null
    E pollFirst(long timeout, TimeUnit unit)获取并移除此双端队列的第一个元素,必要时将在指定的等待时间等待可用元素
    E pollLast()获取并移除此双端队列的最后一个元素;如果此双端队列为空,则返回 null
    E pollLast(long timeout, TimeUnit unit)获取并移除此双端队列的最后一个元素,必要时将在指定的等待时间内等待可用元素
    void putFirst(E e)将指定的元素插入此双端队列的开头,必要时将一直等待可用空间
    void putLast(E e)将指定的元素插入此双端队列的末尾,必要时将一直等待可用空间
    boolean removeFirst()获取并移除此双端队列第一个元素
    boolean removeLast()获取并移除此双端队列的最后一个元素
    E takeFirst()获取并移除此双端队列的第一个元素,必要时将一直等待可用元素
    E takeLast()获取并移除此双端队列的最后一个元素,必要时将一直等待可用元素
  13. 条件变量:条件变量是针对锁的调度

    接口说明
    Condition c = new ReentrantLock().newCondition();条件变量的实例化是通过一个Lock对象上调用newCondition()方法来获取的,这样,条件就和一个锁对象绑定起来了。
    class A {
        private Lock lock = new ReentrantLock();
        Condition c1 = lock.newCondition();
    
        void test1() throws InterruptedException {
            lock.lock();
            System.out.println("等待开始");
            c1.await();
            System.out.println("等待结束");
            lock.unlock();
        }
        void test2() {
            lock.lock();
            c1.notifyAll();
            System.out.println("已唤醒");
            lock.unlock();
        }
    }
    
    1. 在持锁的情况下,可以等待和唤醒
    2. 可以实现多对象同时唤醒
  14. 原子量:所谓的原子量即操作变量的操作是“原子的”,该操作不可再分,因此是线程安全的。

    接口说明
    AtomicInteger整型原子量
    AtomicLong长整型原子量
    AtomicBoolean布尔类型原子量
    AtomicIntegerArray整型数组原子量
    AtomicLongArray长整型数组原子量
    AtomicReference<?>对象原子量
    AtomicReferenceArray<?>对象数组原子量
    1. AtomicInteger原子量常用方法:

      方法说明
      public final int get(int i)获得数组第i个下标的元素
      public final int length()获得数组的长度
      public final int getAndSet(int i, int newValue)将数组第i个下标设置为newValue,并返回旧的值
      public final int getAndIncrement(int i)将第i个下标的元素加1
      public final int getAndDecrement(int i)将第i个下标的元素减1
      public final int getAndAdd(int i, int delta)将第i个下标的元素增加delta(delta可以是负数)
    2. AtomicIntegerArray原子量常用方法

      方法说明
      public final int get(int i)获得数组第i个下标的元素
      public final int length()获得数组的长度
      public final int getAndSet(int i, int newValue)将数组第i个下标设置为newValue,并返回旧的值
      public final int getAndIncrement(int i)将第i个下标的元素加1
      public final int getAndDecrement(int i)将第i个下标的元素减1
      public final int getAndAdd(int i, int delta)将第i个下标的元素增加delta(delta可以是负数)
      1. 即便是原子量,依然要做线程同步
      2. 保证多个线程对同一个数据的可见性和线程安全性
  15. 障碍器

    接口说明
    CyclicBarrier cb = new CyclicBarrier(7,new MainTask());如一个大型的任务,常常需要分配好多子任务去执行,只有当所有子任务都执行完成时候,才能执行主任务,这时候,就可以选择障碍器

    image-20210507080309247

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

隐 风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值