LichongQ / record

for record something necessary
0 stars 0 forks source link

并发与多线程 #10

Open LichongQ opened 6 years ago

LichongQ commented 6 years ago

问题:java.util.ConcurrentModificationException 原因: modCount在遍历的时候被修改 解决:CopyOnWriteArrayList
参考链接:https://www.jianshu.com/p/c5b52927a61a fail-fast:https://blog.csdn.net/chenssy/article/details/38151189

LichongQ commented 6 years ago

多线程的等待通知机制 ReentrantLock和Condition的await和signal等待通知机制:https://www.jianshu.com/p/28387056eeb4 Object.wait和notify配置对象monitor的等待通知机制,java底层级别的实现;ReentrantLock+Condition语言级别的实现 synchronize的字节码实现是monitorenter和monitorexit --- synchronized可以自动释放锁 线程间通信Condition:通过 ReentrantLock.newcondition()创建codition实例 condition.await condition.signal/signalAll

LichongQ commented 6 years ago

迭代器 单线程时,遍历删除/添加容器元素时,考虑使用迭代器;多线程时,考虑使用concurrent包的容器 参考:http://blog.51cto.com/tianxingzhe/1693218 join Thread.join() 等待该线程终止

LichongQ commented 6 years ago

ThreadLocal 应用条件:变量是同一个,但是多个线程都使用相同的初值,即使用同一个变量的副本。 内部实现:ThreadLocal通过Thread类内部实现了ThreadLocalMap。获取变量时,首先获取当前线程的Thread,然后根据当前thread获得ThreadLocal维护的ThreadLocalMap。ThreadLocalMap中以ThreadLocal为key,为每一个线程存储一个变量副本。 易错点:ThreadLocal不是用来处理并发场景下的变量共享和变量同步,不同的线程使用的是不同的变量副本 内存泄露:ThreadLocalMap中的entry与ThreadLocal是弱引用关系,所以ThreadLocal可以独立被GC回收;同时ThreadLocalMap中的set方法在key为null时会清理对应的null,从而避免了ThreadLocal被回收后的内存泄露问题。 参考链接:http://www.jasongj.com/java/threadlocal/

LichongQ commented 6 years ago

线程池

  1. 使用Executor -> ExcutorService -> ... -> ThreadPoolExecutor对象创建线程池 -- 旧方法,比较麻烦 ThreadFactory threadFactory = new NamedThreadFactory("PortalWorkThread");

    BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(WORKQUEUE);
    return new ThreadPoolExecutor(CPUNUM + COREPOOLSIZE, CPUNUM + MAXPOOLSIZE, KEEPALIVETIME,
            TimeUnit.SECONDS, workQueue, threadFactory);
    1. 创建线程池的方法(使用Executors的静态方法创建线程池) Executors.newCachedTheadPool()缓存线程池 阻塞队列:SynchronousQueue直接提交队列,不具有缓存功能 Executors.newFixedThreadPool()固定线程池 :LinkedBlockingQueue Executors.newSingleThreadExecutor()单线程线程池:LinkedBlockingQueue Executors.newScheduledThreadPool()延迟或者定时线程池 :DelayedWorkQueue 参考:https://www.jianshu.com/p/b8197dd2934c image
LichongQ commented 6 years ago

AtomicBoolean 原子性变量 AtomicBoolean.compareAndSet(Boolean expect, Boolean update )如果atomicboolean的值与expect不一致,则返回false,否则更新atomicBoolean实际的值

LichongQ commented 6 years ago

ConcurrentLinkedQueue 和 LinkedBlockingQueue 非阻塞队列和阻塞队列 LinkedBlockingQueue常用于生产者消费者模型:put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来 ConcurerntLinkedQueue 是基于link的无界队列,在offer和peek等操作时,不会阻塞

queue.peek 获取队列头部元素 -- collection.element queue.pool 删除队列头部元素 -- collection.remove queue.offer 队列尾部添加元素 -- collection.add

LichongQ commented 5 years ago

java8中使用CompletableFuture编写异步任务 CompletableFuture<~> completableFuture = CompletableFuture.supplyAsyn(() -> { doThreadSomething; }) -- CompetableFuture.supplyAsyn()方法中封装了CompletableFuture.complete()的调用,这里也是异步设置返回结果值的地方 completableFuture.get()获取competableFuture.complete中设置的结果值

利用其它成员方法,方便实现复杂异步任务控制

LichongQ commented 5 years ago

Future的实现类FutureTask FutureTask.cancel(true): 通过future中断异步执行的FutureTask,当FutureTask正在执行的时候,会触发FutureTask的Thread.interrupt中断线程。如果FutureTask中在阻塞在object.wait(), object.join(),sleep()等时,会触发对应阻塞的InterruptedException,并修改Thread的阻塞状态。 ---- 这在使用cancel(true)的场景下,要尤其注意处理好InterruptedExeption。

LichongQ commented 5 years ago

CountDownLatch 等待线程完成时使用 用并发的线程数初始化countdown,然后在线程完成时countDown;主线程在countDown.await()处等待完成 CountDownLatch.countDown() CountDownLatch.await()