
多线程
文章平均质量分 66
北海冥鱼未眠
道路在身旁!
展开
-
事务方法中保证数据只插入一次方案探究
的值是0,a线程执行到了逻辑代码2,这个时候stamp一定已经被a线程变成了1,此时,线程b这个时候首先获取stamp的值是1,线程a还没有执行完成,也就是事务还没有提交,后面执行插入逻辑的时候当然一样会存在幻读问题,导致b线程还是能够插入成功。首先最简单的方式是在数据层面加入唯一性约束,但是项目中会出现报错,并且这里我们要求不能在数据库层面进行操作,数据的事务的隔离级别必须是可重复读,只能在代码中保证数据插入的数据的唯一性。针对上述的情况,幻读的原因就是a事务的开启在b事务提交之前。原创 2023-08-30 10:50:56 · 988 阅读 · 1 评论 -
线程池ThreadPoolExecutor源码解析
否则,退出线程将同时中断那些尚未中断的线程。试想一下,如果我们一个比价大型的项目,,每次需要用到多线程都new一个线程,那么这就会导致线程的创建数量我们不好管理和控制,另外创建和销毁线程的开销还是比较大的,甚至有的时候都已经超过了我们这个线程本身执行这个任务所需要的资源耗,这就是非常不合理的了。我们可以看一下这个方法,我们可以发现这个线程里面不断地调用阻塞队列里面的线程,然后调用它的run方法执行任务,所以实际上没有创建新的线程,你可能比较好奇为这个执行run方法的线程是哪里来的。这样运算好像效率更高。原创 2023-01-16 23:23:44 · 512 阅读 · 0 评论 -
生产者和消费者模式
具有任务顺序的生产者消费者模式。原创 2022-03-21 19:51:28 · 206 阅读 · 0 评论 -
多线程设计模式-保护性暂停模式
有这么一个场景,我们有两个线程,其中一个线程需要等待获取另外一个线程的执行结果,之气那我们是使用join方法可以实现,现在我们不用jon来实现。同时我们可以看一下join方法的底层实现原理,这里面也用到了超时等待,我们上面所写的就是join超时等待的实现原理。上面都是单任务的情况,我们还可以对上面的代码进行修改,改成多任务的版本。并创建一个公共类用来存放GuardedObject 类。同时然后编写业务类,分别添加任务和获取执行的结果。在GuradeObject类中加入以下代码。最后编写代码进行测试。原创 2022-12-25 13:41:44 · 232 阅读 · 0 评论 -
sleep、interrupt等线程相关方法介绍
另外,打断处于执行在sleep,wait,join等方法的线程会将改线程的打断状态标记为false,表示没有被打断。如果打断的是正常执行的线程,则会将打断状态改成true,但是实际上只是修改了这个标记,并没有真的打断线程的执行,如果我们想让这个打断生效需要自己编写业务逻辑的代码让我们的线程终止。用interrupt方法打断处于park的线程,会将这个线程的打断状态置为true,并且如果再次执行park方法并不能暂停线程的执行,这也是park方法的特点,只能打断打断标志是false的线程。原创 2022-01-17 13:40:25 · 1643 阅读 · 0 评论 -
线程间通信方式
因为如果不判断的话第一个线程执行完之后唤醒第二个,第二个执行完结束了,没有办法唤醒第三个等待的线程了。注意这里面还是需要注意一下的,比如实现打印完成之后线程结束,这里面就要进行if判断了。三个线程分别交替打印A、B、C,打印100次。基于Lock锁的Condition实现线程通信。基于synchronized 锁的实现方式。对第二种方式进行重构优化。原创 2022-08-20 00:44:38 · 95 阅读 · 0 评论 -
关于Semaphore信号量的源码解读
非公平锁,因为在对列中排队的线程,只有头结点的后继节点有资格可以获取锁,而在获取许可证时,有其他的线程(不是同步对列中的线程)进入,尝试去获取许可证,这两个线程都有可能获取到许可证,这就是非公平锁的特点。从上面的分析中可以看到,多态的特性,很多方法在执行的时候并不是我们直接点的进去的,而是根据实际的类型觉得调用哪些方法,所以分析的时候千万不要只是点进去某个方法,不然运行的时候可能不是这个方法。公平锁,就是只有队首的节点线程,可以获取许可证,有其他的线程在获取许可证时,会被加入到队尾,等待获取锁。...原创 2022-08-15 00:41:07 · 234 阅读 · 0 评论 -
LongAdder类和AtomicInteger类
voliate关键在保证可见性但是不保证原子性,多线程下还是有线程安全问题。不使用voliate情况下:使用voliate情况下:换成使用线程安全的类也可以使用LongAdder类来实现线程安全LongAdder类在 LongAdder 中维护了一个 Cell 数组,当 Cell 它不为空时,size 是 2 的次幂大小,每个 Cell 数组里面都有一个初始值为 0 的 long 变量,用来存储每个 Cell 的值:LongAdder 引入了分段累加的概念,内部一共原创 2022-05-02 15:16:53 · 679 阅读 · 0 评论 -
两个线程调用同一个对象的同一个方法
两个线程调用同一个对象的同一个方法,会怎么样?public static void main(String[] args) {// System.out.println(String.valueOf(null)); Test test = new Test(); new Thread(new Runnable() { @Override public void run() { t原创 2022-03-12 17:49:40 · 1842 阅读 · 0 评论 -
ThreadLocal的学习
ThreadLocal叫做线程变量,意思是ThreadLocal中填充的变量属于当前线程,该变量对其他线程而言是隔离的,也就是说该变量是当前线程独有的变量。ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。class ThreadLocaDemo { private static ThreadLocal<String> localVar = new ThreadLocal<String>(); static voi原创 2022-03-04 18:44:32 · 227 阅读 · 0 评论 -
Java多线程、线程池
Java中线程的六种状态新建可运行阻塞等待超时等待终止处于可运行状态下的线程才有可能获取CPU的时间片,状态之间切换如下图(摘自黑马教程)新建当一个线程对象被创建,但还未调用 start 方法时处于新建状态此时未与操作系统底层线程关联可运行调用了 start 方法,就会由新建进入可运行此时与底层线程关联,由操作系统调度执行终结线程内代码已经执行完毕,由可运行进入终结此时会取消与底层线程关联阻塞当获取锁失败后,由可运行进入 Monitor 的原创 2022-03-04 09:22:33 · 327 阅读 · 0 评论