java并发包和多线程

1. LockSupport比Object的wait/notify有两大优势

    ①LockSupport不需要在同步代码块里 。所以线程间也不需要维护一个共享的同步对象了,实现了线程间的解耦。

    ②unpark函数可以先于park调用,所以不需要担心线程间的执行的先后顺序。

2. atomic基本原子类

 compareAndSwapInt()通过原子的方式将期望值和内存中的值进行对比,如果两者相等,则执行更新操作。
 staticFieldOffset()和objectFieldOffset()两方法分别提供两静态、非静态域的偏移量计算方法。

3. ReentrantLock和ReentrantReadWriteLock,在读和写都有的情况下选则可重入读写锁

4. StampedLock是Java8引入的一种新的所机制,简单的理解,可以认为它是读写锁的一个改进版本,读写锁虽然分离了读和写的功能,使得读与读之间可以完全并发,但是读和写之间依然是冲突的,读锁会完全阻塞写锁,它使用的依然是悲观的锁策略.如果有大量的读线程,他也有可能引起写线程的饥饿

而StampedLock则提供了一种乐观的读策略,这种乐观策略的锁非常类似于无锁的操作,使得乐观锁完全不会阻塞写线程

5.乐观锁和悲观锁

  即加锁是一种悲观策略,无锁是一种乐观策略,因为对于加锁的并发程序来说,它们总是认为每次访问共享资源时总会发生冲突,因此必须对每一次数据操作实施加锁策略。而无锁则总是假设对共享资源的访问没有冲突,线程可以不停执行,无需加锁,无需等待,一旦发现冲突,无锁策略则采用一种称为CAS的技术来保证线程执行的安全性

CAS在cpu的支持下是原子性操作

扫描二维码关注公众号,回复: 5830530 查看本文章

 

 

6. ArrayBlockingQueue是一个边界缓冲对流,底层是array,他是FIFO先进先出的。新插入的数据会被插入到队列的末尾,而且总是从队头取数据。

7. ConcurrentLinkedDeque有数目不详的元素列表,你可以添加、阅读、或删除任何位置的元素。

    此外并发列表允许不同的线程列  表中添加或删除元素时不产生任何数据不一致, 非阻塞列表提供如下操作,

     如果操作不能立即完成,列出抛出异常或者返回一个null值

 

8. CountDownLatch利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,

    此时就可以利用CountDownLatch来实现这种功能了。

 

9. CyclicBarrier通过它可以实现让一组线程等待至某个状态之后再全部同时执行。叫做回环是因为当所有等待线程都被

  释放以后,CyclicBarrier可以被重用。我们暂且把这个状态就叫做barrier,当调用await()方法之后,线程就处于barrier了

 

10 CountDownLatch和CyclicBarrier区别:

    CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:

    CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;

   CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;

    另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。

 

11. Semaphore可以控同时访问的线程个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。

    Semaphore其实和锁有点类似,它一般用于控制对某组资源的访问权限。

 

==============================多线程==================================================
1.Executor 是所有和线程有关的接口;   

2. countDownLatch:  来使用他做统计用,多个线程都执行完毕后,数据统一返回;

       他相当于一个计数器功能, countdown方法是对count进行减一操作, 最后在await(); 方法;

        检测count如果不为0,所有线程等待,未完成的线程返回结果; 最后统计返回个前端;

3. ThreadPoolExecutor实现了AbStractExectorServic,

     他的构造方法参数有:

        ①.核心线程数,默认核心线程一直存活

        ② 线程池所容纳的最大线程数,超过这个数会被阻塞.在LinkedBlockingDeque时候才无效

        ③. keepAliveTime ,非核心线程闲置时间,超过这个时间会被回收

        ④. unit, 闲置单位

        ⑤. 线程池中任务队列;  

              synchronousQueue:  在核心线程用完了,就会在最大线程数情况下创建线程,超过后抛异常;

              linkedBlockingDeque: 他就是超过核心线程数,就放在队列中排队;

              ArrayBlockingQueue: 是一个阻塞式的队列,数组式的,性能不好,稳定;

       ⑥. threadFactory线程工厂可以对线程属性定制

       ⑦. RejectedEecutionHandler:  当添加新线程被拒绝的时候,会执行他的方法;

4.ExecutorService 是Executor的子接口 , 开启线程池的方法;

   创建四种线程池:

   ①newFixedThreadPool 创建一个定长的线程,超出的线程会在队列中等待

   ②.newScheduledThredPool 创建一个定长的线程池,支持定时及周期性任务执行.

   ③.newCachedThreadPool 川建一个可缓存的线程池,如果线程池长度超过处理需要,可以灵活回收,若无可回收线程,则创建线程

   ④newSingleThreadExecutor 创建一个单线程化的线程池, 只会用唯一工作线程来执行任务,保证任务顺序执行优先级执行;

    

5. ThreadPoolTaskExecutor 异步方法;

   ①.无返回值的任务使用execute(Runnable)

   ②.有返回值使用submit(Runnable) , 使用Future对象封装返回值.

         shutdown则只是将线程池的状态设置为shutdown,然后中断所有没有执行任务的线程,并将剩余的任务执行完。

         通过继承线程池,重写beforeExecute,afterExecute和terminated方法来在线程执行任务前,
        线程执行任务结束,和线程终结前获取线程的运行情况,根据具体情况调整线程池的线程数量。

        TaskExecutor.execute(new OverDueTask(orderInfoRedis, now))  异步方法;


   比如 渠道统计:

    一张渠道表:  设及到子父级渠道;

   一张用户注册表:  用户注册时,统计的百分比,

   一张用户详细信表: 还有用户详细表中用户渠道首次借款超过10天统计状态 到底统不统计

   一张订单表:  用户首次借款额度;借款成功次数,

   筛选条件为用户注册时间 开始日期到结束日期;

  首先就是判断用户选择日期间隔,是否大于10天

   大于10天: 两天一个线程  

   小于10天: 一天一个线程

猜你喜欢

转载自blog.csdn.net/xc123_java/article/details/88998046
今日推荐