JUC
1.JUC概述
1.JUC是一个Java安全类的工具包,主要作用与高并发场景;
2.LOCK锁
1.定义Lock时ReentrantLock()中默认是非公平锁(false),公平锁需手动添加true到方法中,公平锁可执行先来后到机制,非公平锁允许插队,之所以默认非公平是为了更好的利用资源和提高效率,因为当先来的优先级低,耗时久,那么会导致后来优先级高,耗时短的进入阻塞;
2.synchronized和lock再区别:sync是内置的Java关键字,灵活度低,非公平,可重入锁(不可设),而lock是一个Java类,灵活度高,可重入。sync无法判断获取锁的状态(自动),而lock可以(手动)。sync当出现获得锁的线程阻塞了,那么其他需要该锁的线程只能跟着阻塞,而lock可以调用trylock()方法尝试让其他线程获取该锁。
3.锁的对象是方法的调用者!需要区分是不是静态,若是静态无论多少把锁都只是一把锁,调用者是类方法,锁的是class,遵守先进先出,反之则区分调用者是否一致;
3.虚假唤醒
1.if主要为判断一次,在生产消费模式下容易产生虚假唤醒,例如唤醒多个线程同时进行加1操作,一般采用while循环防止虚假唤醒;
4.Condition
1.通过lock解决生产消费模式下,线程通信通过Condition实现,await()为等待,signalAll()为唤醒;
2.condition可以精准唤醒,只要多创建几个condition对象即可,Condition c1(2…)=lock.newCondition();c1(2…).signal();
5.ConcurrentModificationException
1.并发修改异常,主要出现在并发的不安全的集合(list,map,set);
2.解决list时创建一个关于Collections.synchronizedList(new ArrayList<>())或CopyOnWriteArrayList<>()(读写分离,避免了写入时覆盖读取的数据,推荐)或Vector()的对象;
3.解决set时和list一样,方法名只是set替换list。map除了上述的collection还有ConcurrentHashMap<>();
6.三大常用辅助类
1.CountDownLatch()(减法计数器):倒计时操作,参数即为倒计时,调用countDown()方法进行减一倒数,为零时通过await()执行下一步;
2.CyclicBarrier()(加法计数器):参数为收集数和方法体,收集满足后通过await()方法执行下一步;
3.Semaphore()(信号量):参数为整数,规定了同一时间只能有参数规定的数量获得线程,acquire()获取线程,release()释放线程,主要用于限流;
7.读写锁
1.读可多线程,写只能一个线程,即写不可插队(独占锁),读可插队(共享锁);
2.new ReentrantReadWriteLock().writeLock()为写锁,…readLock()为读锁;
3.读-读可共存,读-写,写-写不可;
8.阻塞队列
1.类似银行等候室,服从先进先出,类似生产消费模式;
2.同步队列,严格执行一进一出,即只可存放一个元素,BlockingQueue syncq=new SynchronousQueue<>();
3.BlockingQueue的4组API
会抛异常的添加/释放:add(i)/remove();
不会抛异常且有返回值的添加/释放:offer(i)/poll();
不抛异常一直等待的添加/释放:put(i)/take();
不抛异常且可设置超时退出的添加/释放:offer(i,时间,时间类型)/poll(时间,时间类型);
9.池化技术
1.程序的运行本质就是占用系统资源,而池化就是优化资源使用,事先准备一些资源提供程序使用;
2.线程池好处主要是线程复用,可控最大并发数和管理线程;
10.线程池
1.3大方法
ExecutorService e=Executors.newSingleThreadExecutor();//线程池为1
ExecutorService e1=Executors.newFixedThreadPool(5);//线程池为5
ExecutorService e2=Executors.newCachedThreadPool();//线程池不设,看cpu而定
2.7大参数
线程池的调用一般不使用上述3大方法使用,而是调用底层代码ThreadPoolExecutor()创建
ExecutorService threadPool=new ThreadPoolExecutor(
2,//核心线程数
6,//最大线程数,线程超过核心数后逐一开放
2,//超时时间, TimeUnit.SECONDS,//类型
new ArrayBlockingQueue<>(3),//阻塞队列,暂存多余线程
Executors.defaultThreadFactory(),//线程工厂
//拒绝策略,线程>max+queue触发
new ThreadPoolExecutor.CallerRunsPolicy()//不抛异常,线程池满后由原线程执行,默认main线程
);
3.4大拒绝策略
new ThreadPoolExecutor.AbortPolicy()//抛出异常,不处理
new ThreadPoolExecutor.CallerRunsPolicy()//不抛异常,线程池满后由原线程执行,默认main线程
new ThreadPoolExecutor.DiscardOldestPolicy()//不抛异常,和最老的争夺
new ThreadPoolExecutor.DiscardPolicy()//不抛异常,直接结束整个线程
11.CPU密集型和IO密集型
1.线程的最大线程数只要通过CPU密集型(看cpu逻辑核数,定义和核数一致)和IO密集型决定(看程序中高耗IO线程个数,一般定义最大为它的两倍);
12.函数式接口
1.函数式接口(function interface)是只有一个方法的接口;
2.断定型接口(predicate)就是有输入参数,返回值只为布尔值的函数式接口;
3.消费型接口(consumer)是只有输入,没有返回值的函数式接口;
4.供给型接口(supplier)是没有参数只有返回值的函数型接口;
13.Stream流计算
1.集合本质用于存储,stream流本质是计算;
2.集合.stream().方法
//集合即存储
List list= Arrays.asList(u1,u2,u3,u4,u5,u6);
//流即机算
list.stream()
.filter(user -> {return user.getId()%2==0;})//求偶
.filter(user -> {return user.getAge()>23;})//比较
.map(user -> {return user.getName().toUpperCase();})//字符串全大写
.sorted((U1,U2)->{return U2.compareTo(U1);})//对比
.limit(1)//限制
.forEach(System.out::println);//输出
3.上述代码的流计算还用到了lambda表达式和链式编程的思想;