并发
文章平均质量分 73
涛堆堆
一个学java的开发小白
展开
-
并发-自定义线程池
Thread Pool:放置这些可以重用的线程Blocking Queue:阻塞队列,体现生产者-消费者模式下,平衡它们之间速度差异线程池中的线程相当于任务的消费者,main线程相当于任务的生产者。原创 2023-08-17 17:30:49 · 36 阅读 · 1 评论 -
并发-ReentrantLock详解
synchronized中也有条件变量,就是waitSet,但ReentrantLock支持多个条件变量。一个线程如果首次获得了这把锁,那么因为它是这把锁的拥有者,因此有权利再次获得这把锁。ReentrantLock默认是不公平的,可以通过构造方法设置。如果是不可重入的,第二次获得锁的时候会被锁挡住。为了避免死等,减少死锁,属于被动避免。相对synchronized。原创 2023-08-17 17:28:38 · 37 阅读 · 1 评论 -
并发-共享模型-无锁
性能提升的原因:在竞争时,设置多个累加单元,Thread-0累加Cell[0],而Thread-1累加Cell[1]…但无锁情况下,因为线程要保持运行,需要额外CPU的支持,虽然不会进入阻塞,但由于没有分到时间片,仍然会进入可运行状态,还会导致上下文切换。,即使重试失败,线程始终在高速运行没有停歇,而synchronized会让线程在没有获得锁的时候发生上下文切换,进入阻塞。利用字段更新器,可以针对对象的某个域(Field)进行原子操作,只能配合 volatile 修饰的字段使用,否则会出现 异常。原创 2023-08-17 17:27:59 · 26 阅读 · 1 评论 -
并发-JAVA内存模型解析及volatile原理
它用来修饰成员变量和静态成员变量,他可以避免线程从自己的工作缓存中查找该变量的值,必须到主存中获取它的值,线程操作volatile变量都是直接操作主存,解决可见性问题。JMM定义了主存(所有线程都共享的数据)和工作内存(每个线程都私有的数据)抽象概念,底层对应着CPU寄存器、缓存、硬件内存、CPU指令优化等。读屏障(lfence)保证在该屏障之后,对共享变量的读取,加载的是主存中的最新数据(保证可见性 )写屏障(sfence)保证在该屏障之后,对共享变量的改动,都同步到主存中(保证可见性)原创 2023-08-17 17:26:20 · 43 阅读 · 1 评论 -
并发-深入分析synchronized
如果尝试加轻量级锁的过程中,CAS操作无法成功,这时一种情况就是有其他线程为此对象加上了轻量级锁(有竞争),这时需要进行锁膨胀,将轻量级锁变为重量级锁。当退出synchronized代码块(解锁时)如果有取值为null的锁记录,表示有重入,这时重置锁记录,表示重入计数减一。当退出synchronized代码块时,锁记录的值不为null,这时使用CAS将MarkWord的值恢复给对象头。轻量级锁对使用者是透明的,语法仍是synchronized,会优先使用轻量级锁加锁,如果加锁失败才会用重量级锁。原创 2023-08-17 17:24:55 · 46 阅读 · 1 评论 -
并发-Monitor详解
每个Java对象都可以关联一个Monitor对象(操作系统提供的),如果使用synchronized给对象上锁(重量级)之后,该对象头的Mark Word中就被设置指向Monitor对象的指针。Monitor被翻译为。Monitor结构如下。原创 2023-08-17 17:20:44 · 47 阅读 · 1 评论 -
并发-线程运行原理剖析
当Context Switch发生时,需要由操作系统保存当前线程的状态,并恢复另一个线程的状态,java中就是用程序计数器完成,它记住下一条jvm指令的执行地址。用setDaemon()设置守护进程,垃圾回收器就是一种守护进程,java应用结束了,垃圾回收线程也会停止。只要等其他的非守护线程运行结束了,即使守护进程的代码没有执行完,也会强制结束。因为以下一些原因导致cpu不再执行当前的线程,转而执行另一个线程的代码。打断正常运行的线程,不会清空打断状态。打断park线程,不会清空打断状态。原创 2023-08-17 17:17:58 · 42 阅读 · 1 评论 -
并发-创建线程的多种方式
在runable传入Thread对象时,Thread里面的run方法,会判断如果有runnable对象,会优先采用runnable对象的run方法;用Runnable更容易和线程池等高级API配合,且让任务类脱离了Thread继承体系,更灵活。把【线程】和【任务】(线程要执行的任务代码)分开。原创 2023-08-17 17:15:50 · 28 阅读 · 1 评论