卷土重来…
生如蝼蚁,当立鸿鹄之志,命如纸薄,应有不屈之心!
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
64.ThreadLocal造成的内存泄漏
程序中已动态分配的堆内存,由于某种原因程序为释放和无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。内存泄漏的堆积终将导致内存溢出。原创 2024-06-30 14:12:12 · 548 阅读 · 0 评论 -
63.ThreadLocal原理
每个Thread维护一个ThreadLocalMap,这个map的key是ThreadLocal实例本身,value才是真正要存储的值Object。Thread原创 2024-06-29 23:13:13 · 197 阅读 · 0 评论 -
62.ThreadLocal在数据库Connection对象上的应用
1.使用的连接必须是同一个:service层开启事务的connection需要跟dao层访问数据库的connection保持一致。使用完Connection对象,关闭Connection连接的时候,需要调用ThreadLocal的。1.传递数据,保存每个线程绑定的数据,在需要的地方可以直接获取,避免参数直接传递带来的代码耦合问题。2.如果连接对象是空的,再去连接池中获取连接对象,将此连接对象跟当前线程进行绑定。2.线程隔离,各线程之间的数据相互隔离却又具备并发性,避免同步方式带来的性能损失。原创 2024-06-29 22:05:02 · 230 阅读 · 0 评论 -
61.ThreadLocal认识和使用
ThreadLocal类用来提供给线程内部的局部变量。这种变量在多线程环境下访问(通过get和set方法访问)时能保证各个线程的变量相对独立于其他线程内的变量。ThreadLocal实例通常来说都是类型的,用于关联线程和线程上下文。:提供线程内的局部变量,不同的线程之间不会相互干扰,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的复杂度。1.线程并发:在多线程并发场景下。原创 2024-06-29 18:47:57 · 695 阅读 · 0 评论 -
60.线程安全的集合类
大部分实现基于锁,一般使用的是ReentrantLock锁,提供用来阻塞的方法。修饰的安全集合 SynchronizedMap,SynchronizedList,性能不高,不推荐。HashTable,Vector 底层使用的Synchronized加锁实现的,性能不高,不推荐。J.U.C安全集合: Blocking类,CopyOnWrite类,Concurrent类。,通过拷贝的方式来避免多线程读写时的线程安全。使用与读多写少的场景。,性能高,内部很多操作使用cas优化,一般提供较高的吞吐量。原创 2024-06-10 10:14:32 · 176 阅读 · 0 评论 -
59.CyclicBarrier
与CountdownLatch比较,CyclicBarrier是可以重用的。CountdownLatch每次都要创建新的对象,计数个数一旦设置也不能修改。一个任务执行到await方法时候,会等待。直到两个任务都执行到await方法时候,就会继续执行。就是第一次的task1和第二次的task1先执行完,触发 结果线程的运行,这就不对了。循环栅栏,用来进行线程协作,等待线程满足某个计数。构造时设置计数个数。原创 2024-06-09 22:36:30 · 101 阅读 · 0 评论 -
58.CountdownLatch
用来进行线程同步协作,等待所有线程完成倒计时。构造参数用来初始化等待计数值,await方法用来等待计数归零,countDown方法用来让计数减一。原创 2024-06-09 22:02:03 · 221 阅读 · 0 评论 -
57.Semaphore信号量
Semaphore实现简单连接池,对比享元模式下的实现用wait,notify。性能和可读性显然更好。用来限制能同时访问共享资源的线程上限。只是适合限制单机线程数量。原创 2024-06-09 20:24:34 · 113 阅读 · 0 评论 -
56.StampedLock
jdk8加入的,为了进一步优化读性能。但是却无法完全替代。,如果校验通过,表示这期间确实没有写操作,数据可以安全使用,如果校验没有通过,需要重新获取读锁,保证数据安全。乐观读,StampedLock支持tryOptimisticRead()方法(乐观读),读取完毕后需要做一次。两个线程读操作,都通过乐观读拿到了数据。读读并发,不会加读锁,是乐观读取。一个线程读数据,一个线程写数据,乐观读就会升级为读锁。1.不支持条件变量,没有signal和await。特点:在使用读锁、写锁时都必须配合。原创 2024-06-09 19:11:05 · 114 阅读 · 0 评论 -
55.ReentrantReadWriteLock应用于缓存
模拟一个数据层dao数据层带缓存的dao测试代码结果。原创 2024-06-09 15:13:10 · 504 阅读 · 0 评论 -
54.ReentrantReadWriteLock
当读操作远远高于写操作时,用读写锁让读可以并发,提高性能。读写是互斥的。使用读锁保护数据的read方法,写锁保护数据的write方法。原创 2024-06-09 12:46:41 · 119 阅读 · 0 评论 -
53.ReentrantLock原理
ReentrantLock 实现了Lock接口, 内置了Sync同步器继承了AbstractQueuedSynchronizer。Sync是抽象类,有两个实现NonfairSync非公平,FairSync公平。所以ReentrantLock有公平锁和非公平锁。默认是非公平锁。ReentrantLock构造器是使用的非公平同步器。原创 2024-06-09 10:34:11 · 124 阅读 · 0 评论 -
52.Fork & Join线程池
jdk1.7之后加入的新的线程池的实现。实现一种分治的思想。适用于能够进行任务拆分的cpu密集型运算。原创 2024-06-08 11:06:18 · 92 阅读 · 0 评论 -
51.线程池大小
1.线程池太小会导致程序不能充分利用系统资源、容易导致饥饿。2.线程池过大导致更多的线程上下文切换,占用更多的内存。原创 2024-06-07 21:41:46 · 295 阅读 · 0 评论 -
50.异步模式-工作线程
让有限的工作线程来轮流处理无限多的任务。归类为分工模式。典型实现就是线程池,体现了经典设计模式:享元模式。不同任务类型应该使用不同的线程池,这样能够避免饥饿,并能提升效率。原创 2024-06-07 21:23:20 · 396 阅读 · 0 评论 -
49.线程池的关闭方法
调用shutdown后,由于调用线程并不会等待所有任务运行结束,因此如果它想在线程池TERMINATED后做些事情,可以利用此方法等待。但是我们并不知道线程池中的任务多久才能全部执行完,也就无法知道awaitTermination方法设置的超时时间是多久。还是可能用submit方法返回的future结果来判定线程池中的每个任务是否执行完毕。只要线程池的状态不是RUNNING, 此方法就返回true。4.并用interrupt的方式中断正在执行中的任务。判断线程池的状态是否为TERMINATED。原创 2024-06-06 22:54:00 · 257 阅读 · 0 评论 -
48.线程池提交任务的方法
带超时时间的invokeAll方法,如果规定的时间没有线程池中的任务没有执行完,会把后续的取消掉。任务集合中只要有一个任务执行完就返回结果,并取消其它任务。提交任务task,用返回值Future获得任务执行结果。提交一个任务集合,返回任务集合的所有执行结果。用于主线程接受线程池中线程的返回结果。带超时的invokeAny方法。原创 2024-06-06 21:56:21 · 545 阅读 · 0 评论 -
47.各种类型的线程池
);});});});原创 2024-06-05 23:23:46 · 288 阅读 · 0 评论 -
46.ThreadPoolExcutor接口
ThreadPoolExcutor使用int高3位来表示线程池状态,低29位表示线程数量从数字上比较:RUNNING 111, 最高位1表示负数。原创 2024-06-03 23:20:36 · 395 阅读 · 0 评论 -
45.自定义线程池(三)-拒绝策略
在原来的基础上添加了 带超时时间的阻塞添加方法,offer方法。原创 2024-06-03 22:10:30 · 1334 阅读 · 0 评论 -
44.自定义线程池(二)
执行15个线程,自定义线程池有两个线程,让每个线程执行任务时间特别长,队列的容量为10。原创 2024-06-02 20:35:16 · 330 阅读 · 0 评论 -
43.自定义线程池(一)
因为调用了BlockingQueue的take方法,当队列为空的时候,会无限循环等待,所以这两个线程一直没有结束。可以调用带超时的poll方法,超时后,线程就会结束,也从线程集合中移除。阻塞队列,线程池中的线程会从阻塞队列中去拿任务执行。任务多了线程池处理不过来了,就会到Blocking Queue中排队,等待执行。链表结构,特点是先进先出。是线程池,里面是一定数量的线程,是消费者。就是生产者,不断产生新的执行任务。是一个双向链表,操作起来更方便。原创 2024-06-02 19:52:09 · 420 阅读 · 0 评论 -
42.AQS
属性表示资源的状态:独占模式,共享模式。子类需要定义如何维护这个状态,控制如何获取锁和释放锁。7.条件变量来实现等待,唤醒机制,支持多个条件变量,类似于Monitor的WaitSet。4.独占模式:只有一个线程能访问这个资源。使用Synchronized锁就是独占模式。1.AQS, AbstractQueuedSynchronizer,是。5.共享模式:允许有多个线程访问资源。2.阻塞式的锁就类似于Synchronized锁。,类似于Monitor的EntryList。tryAcquire 获取锁。原创 2024-04-18 20:19:46 · 390 阅读 · 0 评论 -
41.ScheduledThreadPool线程池实现定时任务
利用ScheduledThreadPool线程池实现定时任务。LocalDateTime的使用;Duration的使用;原创 2024-04-17 22:54:48 · 542 阅读 · 0 评论 -
40.任务调度线程池
同一时刻两个任务得到执行,相互不受影响。但是如果coreSize设置为1,那么就要等task1执行完了才能执行其他的任务,也就是串行执行。这个间隔时间是从上一次执行任务开始就开始算的。如果任务执行时间大于间隔时间,就以任务执行时间为准,反之以间隔时间为准。在任务调度线程池功能加入之前,可以使用java.util.Timer来实现定时功能,Timer优点在于简单易用,是由于所有的任务都是由同一个线程来调度,因此所有的任务都是。如果某个任务出现异常也不会影响其它任务的执行,,同一时间只能有一个任务在执行,原创 2024-06-07 23:43:37 · 137 阅读 · 0 评论 -
39.原子更新器
保证对对象属性的更新具有原子性。原创 2024-04-07 22:50:23 · 179 阅读 · 0 评论 -
38.java8函数式接口
Supplier<T> 提供者,无中生有。无参数,有结果。 Function<T> 函数。一个参数,一个结果。 BiFunction(参数1,参数2)->结果。 Consumer消费者,一个参数没有结果。 BiConsumer 两个参数没有结果。原创 2024-04-07 22:32:00 · 366 阅读 · 0 评论 -
37.ABA问题
通过AtomicStampedReference的版本号,可以知道数据改了多少次。但是如果在这个过程中,A变成D然后又变成A, 那么再调用compareAndSet去改变也能修改成功B。这个过程中A->D->A,程序是感知不到的。如果主线程希望,只要有其他线程动过这个共享变量,那么自己cas操作就算失败,这时比较值是不够的,需要加入版本号。上面的代码:主线程仅能判断共享变量的值是否与最初的A是否相同,不同感知这种从A变成了B,又变成了A的情景。就会先比较原来的值是否为A,如果为A则修改成功,否则修改失败。原创 2024-04-05 20:42:32 · 400 阅读 · 0 评论 -
36.基于CAS实现的java类
JUC, java.util.concurrent并发工具包下。原创 2024-04-05 19:36:34 · 390 阅读 · 0 评论 -
35.无锁(乐观锁)CAS
synchronized是基于悲观锁的实现,防着其他线程来修改共享变量,我上了锁你们都别改,我改完解开锁,你们才有机会。无锁的情况下,即使重试失败,线程始终在高速运行,没有停歇。CAS是基于乐观锁的实现,最乐观的估计,不怕别的线程来修改共享变量,就算改了也没有关系,我吃点亏再重试。1.因为没有使用synchronized,所以线程不会陷入阻塞,这是效率提升的因素之一。compareAndSet方法是原子的,不可分割的。,因为比较并交换,每次都需要读取共享变量最新的值来实现比较。的方式保护共享资源现成安全。原创 2024-04-05 15:43:37 · 386 阅读 · 0 评论 -
34.单例模式
静态内部类来创建单例-懒汉式。原创 2024-04-05 13:56:35 · 233 阅读 · 0 评论 -
33.Double checked locking
前提条件:如果Synchronized中的变量没有完全受Synchronized管理控制,那么就不能保证有序性,会发生指令重排序的问题。所以Synchronized是不能够保证有序性的,这个时候就需要给变量添加volatile关键字修饰,来保证变量的有序性,防止指令的重排序。前提条件:如果Synchronized中的变量完全受synchronized管理控制,那么就能够保证有序性,不会有发生指令重排序的问题。所以Synchronized是能够保证有序性的。synchronized到底能不能保证 有序性?原创 2024-04-05 11:05:28 · 408 阅读 · 0 评论 -
32.volatile保证指令有序性
jvm在不影响正确性的前提下,可以调整语句的执行顺序。多线程下这种指令重排会影响正确性,而单线程没有问题。volatile修饰就可以解决指令重排序。jvm调整指令执行的顺序叫做指令重排。JIT即时编译器做的一些优化。原创 2024-04-04 22:48:07 · 507 阅读 · 0 评论 -
31.volatile保证可见性
因为t1线程要频繁的从主内存中读取flag的值,JIT编译器会将flag的值缓存到自己工作内存中的高速缓存中,减少对主内存flag的访问,提高效率。1秒之后,main线程修改了flag的值并同步至主存,而t1线程永远从自己工作内存中的高速缓存中读取这个变量的值,结果永远是旧值。避免线程从自己的工作缓存中查找变量的值,线程操作volatile变量都是直接操作主存。volatile修饰的都是多个线程共享的变量,不会修饰局部变量,因为局部变量每个线程都有一份。volatile只能保证可见性,不能保证原子性。原创 2024-04-04 20:06:44 · 265 阅读 · 0 评论 -
30.多个线程交替执行
线程一输出a,5次;线程二输出b,5次;线程三输出c,5次;现在要求输出abcabcabcabcabc怎么实现?原创 2024-04-04 11:12:16 · 366 阅读 · 0 评论 -
29.使线程以固定顺序输出结果
【代码】29.使线程以固定顺序输出结果。原创 2024-04-03 22:29:18 · 501 阅读 · 0 评论 -
28.ReentrantLock-多条件变量
synchronized中也有条件变量,当条件不满足时进入WaitSet等待。ReentrantLock的条件变量比Synchronized强大之处在于它支持多个条件变量。原创 2024-04-03 22:02:40 · 659 阅读 · 0 评论 -
27.ReentrantLock
2.与synchronized相同点都支持锁的可重入。//获取锁try {//必须释放锁同一个线程如果首次获得了这把锁,因为它是这把锁的拥有者,因此有权利再次获取这把锁。如果是不可重入锁,那么第二次获得锁时,自己也会被锁挡住。原创 2024-04-02 23:24:52 · 657 阅读 · 0 评论 -
26.活锁、饥饿锁
两个线程,相互改变了对方结束条件,导致两个线程不能结束。执行时间也都是一样,导致两个线程永远不会结束。解决办法:将执行时间设置成不一样即可。原创 2024-04-01 23:20:02 · 833 阅读 · 0 评论 -
25.死锁
一个线程如果需要同时获取多把锁,就容易产生死锁。t1线程获得A对象锁,接下来想获取B对象的锁。t2线程获得B对象锁,接下来想获取A对象的锁。命令,可以查看当前正在运行的java进程。经典死锁案例:五位哲学家五根筷子吃饭。原创 2024-04-01 23:06:55 · 472 阅读 · 0 评论