保定建设招聘信息网站写软文怎么接单子
Java-线程池 原子性 类
- 线程池
- 构造方法
- 调用Executors静态方法创建
- 调用方法
- 直接创建线程池对象
- 原子性
- volatile-问题
- 出现原因:
- volatile解决
- 原子性
- AtomicInteger的常用方法
- 悲观锁和乐观锁
- synchronized(悲)和CAS(乐)的区别
- 并发工具类
- Hashtable集合
- ConcurrentHashMap
- 原理:
- CountDownLatch
- 方法
- Semaphore
- 方法:
线程池
构造方法
调用Executors静态方法创建
创建一个默认无限大小的线程池(最大不超过int的范围):static ExecutorService newCachedThreadPool() 例:ExecutorService es = Executors.newCachedThreadPool();创建一个指定大小最多线程数量的线程池:static newFixedThreadPool(int nThreads) 例:ExecutorService es = Executors.newCachedThreadPool();
调用方法
Future<?> submit(Runnable task) // 提交一个 Runnable 任务用于执行,()里可以传一个λ表达式,也可以传实现Runnable对象void shutdown 关闭线程池
使用Executors中所提供的静态方法来创建
直接创建线程池对象
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(核心线程数量,最大线程数量,空闲线程最大存活时间,任务队列,创建线程工厂,任务的拒绝策略);
参数一:核心线程数量 --------------> 核心线程数量 (不能小于0)参数二:最大线程数 --------------> 线程池中最大线程的数量 (不能小于等于0,最大数量 >= 核心线程数量)参数三:空闲线程最大存活时间 --------------> 空闲时间(值) (不能小于0)参数四:时间单位 --------------> 空闲时间(单位) (时间单位)(秒:TimeUnit.SECONDS 分:TimeUnit.MINUTES 时:TimeUnit.HOURS ...)参数五:任务队列 --------------> 阻塞队列 (不能为null)(new ArrayBlockingQueue<>(int capacity)) //任务队列参数六:创建线程工厂 --------------> 创建线程的方式 (不能为null)(Executors.defaultThreadFactory())参数七:任务的拒绝策略 --------------> 要执行的任务过多时的解决方案 (不能为null)(new ThreadPoolExecutor.AbortPolicy())
任务的拒绝策略ThreadPoolExecutor.AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常。--是默认的策略。ThreadPoolExecutor.DiscardPolicy: 丢弃任务,但是不抛出异常 这是不推荐的做法。ThreadPoolExecutor.DiscardOldestPolicy: 抛弃队列中等待最久的任务 然后把当前任务加入队列中。ThreadPoolExecutor.CallerRunsPolicy: 调用任务的run()方法绕过线程池直接执行。
原子性
volatile-问题
出现原因:
当A线程修改了共享数据时,B线程没有及时获取到最新的值,如果还在使用原先的值,就会出现问题 1 ,堆内存是唯一的,每一个线程都有自己的线程栈。2 ,每一个线程在使用堆里面变量的时候,都会先拷贝一份到变量的副本中。3 ,在线程中,每一次使用是从变量的副本中获取的。
volatile解决
Volatile关键字 :强制线程每次在使用的时候,都会看一下共享区域最新的值例: public static volatile int money = 1000; //每个线程使用前都会重新获取此值
原子性
所有的操作全部都得到了执行并且不会受到任何因素的干扰而中断,是一个不可分割的整体
AtomicInteger的常用方法
public AtomicInteger() //初始化一个默认值为0的原子型Integer
public AtomicInteger(int initialValue) //初始化一个指定值的原子型IntegerAtomicBoolean: 原子更新布尔类型 //与AtomicInteger相似AtomicLong: 原子更新长整型 //与AtomicInteger相似int get(): //获取值int getAndIncrement(): //以原子方式将当前值加1,注意,这里返回的是自增前的值。int incrementAndGet(): //以原子方式将当前值加1,注意,这里返回的是自增后的值。int addAndGet(int data): //以原子方式将输入的数值与实例中的值(AtomicInteger里的value)相加,并返回结果。int getAndSet(int value): //以原子方式设置为newValue的值,并返回旧值。
悲观锁和乐观锁
synchronized(悲)和CAS(乐)的区别
相同点:在多线程情况下,都可以保证共享数据的安全性。不同点:synchronized总是从最坏的角度出发,认为每次获取数据的时候,别人都有可能修改。所以在每次操作共享数据之前,都会上锁。(悲观锁)cas是从乐观的角度出发,假设每次获取数据别人都不会修改,所以不会上锁。只不过在修改共享数据的时候,会检查一下,别人有没有修改过这个数据。
如果别人修改过,那么我再次获取现在最新的值。
如果别人没有修改过,那么我现在直接修改共享数据的值.(乐观锁)乐观锁:1: 只针对 值的修改 只在修改处 加校验。 具体大段的逻辑 他不管。2: 针对 多查 少改。
悲观锁(synchronized)1: 针对 大段的逻辑 上下文关联的
并发工具类
Hashtable集合
HashMap 线程不安全的 效率比较高。 开发中在局部位置定义双列集合,首选HashMap,因为局部位置不涉及共享数据 ,属于单线程开发,使用HashMap效率最高。Hashtable 每个方法都是 同步方法,用synchronized修饰 。 效率比较低
ConcurrentHashMap
线程安全 效率较高
原理:
jdk1.7之前原理:使用的 哈希表的嵌套, 并使用悲观锁synchronized对 小哈希表进行局部锁定,所以他可以同时使用16条线程共同操作此集合。
jdk1.8之后的原理:对横向的数组数据 使用乐观锁cas对竖向的链表和红黑树 使用悲观锁synchronized 锁对象是红黑树或者链表的头结点。
CountDownLatch
可以设置 某一线程 等待其他几条线程结束之后 再开始执行
方法
构造方法:
public CountDownLatch(int count) 参数传递线程数,表示等待线程数量成员方法:
public void await() 让线程等待
public void countDown() 当前线程执行完毕
Semaphore
限制同一时间线程执行的个数,可以控制访问特定资源的线程数量。
方法:
构造方法:
public Semaphore(int count) // 参数传递可执行的线程数量方法:
public void acquire() //从此信号量获取一个许可,在提供一个许可前一直将线程阻塞
public void release() //释放一个许可,将其返回给信号量。