![](https://img-blog.csdnimg.cn/20201014180756923.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Java 多线程与并发
文章平均质量分 84
Java 多线程与并发
developer@liyong
GISer
展开
-
并发编程-Future 与 FutureTask
如果call()在规定时间内完成任务,那么就会正常获取到返回值,而如果在指定时间内没有计算出结果,则会抛出TimeoutException。FutureTask叫未来任务,可以将一个复杂的任务剔除出去交给另外一个线程来完成。Future是一个接口,FutureTask是一个实现类。原创 2024-02-21 16:58:01 · 360 阅读 · 0 评论 -
并发编程-ThreadLocal
因为弱引用在GC回收时会被回收,如果使用强引用,我们某个方法里面创建了一个ThreadLocal,我们肯定使用了new关键字,这个时候是强引用,如果这个方法结束,对于这个方法的强引用解除了。首先我们看到Thread里面,有一个ThreadLocalMap,可以看到再java1.8之后,每个线程都有自己的ThreadLocalMap。ThreadLocal 是线程本地变量类,在多线程并行执行过程中,将变量存储在ThreadLocal中,每个线程中都有独立的变量,因此不会出现线程安全问题。原创 2023-08-28 22:32:36 · 220 阅读 · 0 评论 -
并发编程-线程池
线程池(ThreadPool) 是一种基于池化思想管理线程的工具,看过new Thread源码之后我们发现,频繁创建线程销毁线程的开销很大,会降低系统整体性能。线程池维护多个线程,等待监督和管理分配可并发执行的任务。降低资源消耗:通过线程池复用线程,降低创建线程和释放线程的损耗提高响应速度:任务到达时,无需等待即刻运行提高线程的可管理性:使用线程池可以进行统一的分片、调优和监控线程提供可扩展性:线程池具备可扩展性,研发人员可以向其中增加各种功能,比如延时,定时,监控等。转载 2024-02-21 14:48:44 · 19 阅读 · 0 评论 -
并发编程-并发容器与队列
CopyOnWrite 思想(保证的是最终一致性):是平时查询的时候,都不需要加锁,随便访问,只有在更新的时候,才会从原来的数据复制一个副本出来,然后修改这个副本,最后把原数据替换成当前的副本。改进一: 取消segments字段,直接采用transient volatile HashEntry[] table保存数据,采用table数组元素作为锁,从而实现了对每一行数据进行加锁,进一步减少并发冲突的概率。put()方法是插入元素,但是如何队列已满,则无法继续插入,则阻塞,直到队列中有空闲空间。原创 2024-02-21 13:19:18 · 835 阅读 · 0 评论 -
并发编程-线程协作工具类
通常会有另一个线程2去执行对应条件,直到这个条件达成时,线程2就会执行condition.signal()方法,此时JVM就会从被阻塞的线程里找到那些等待该condition的线程,当线程1收到可执行信号时,它的线程状态就会变成Runnable可执行状态。我们可以看到,运行结果哦几乎是3个为一组进行输出,是因为这个工具类定义了就只有三个位置,如果三个位置都满了剩下的线程就只能等待,等到有资源释放了继续执行。线程会等待,直到线程到了事先规定的数目,然后触发执行条件进行下一步动作。原创 2024-02-20 23:48:31 · 438 阅读 · 0 评论 -
并发编程-ReentrantLock 与 ReentrantReadWriteLock(可重入锁,独享锁,公平与非公平锁,读写锁)
并且由于是第一个节点,所以这个线程开始执行,所以Thread指向了空,其实也可以继续指向ThreadA,但是其实我们用不到了,因为线程不管是异常还是顺利执行完都会释放资源,就算继续存放ThreadA也没有用武之地了。addWaiter(Node mode)的mode表示节点的类型,Node.EXCLUSIVE表示是独占排他锁,也就是说重入锁是独占锁,用到了AQS的独占模式。我们进入这个方法,发现是一个抽象方法,调用的是子类的方法,分别是公平和非公平锁的实现,我们先看公平锁。原创 2024-02-20 14:48:24 · 1166 阅读 · 0 评论 -
并发编程-JUC-锁分类基础知识
synchronized为Java的关键字,是Java提供的同步机制,当它用来修饰一个方法或一个代码块时,能够保证在同一时刻最多只能有一个线程执行该代码。synchronized同步锁提供了一种排他式的同步机制,当多个线程竞争锁资源时,同时只能有一个线程持有锁,当一个线程获取了锁,其他线程就会被阻塞只有等到占有锁的线程释放锁后,才能重新进行锁竞争。JUC中提供的锁都提供了常用的锁操作,加锁和解锁的方法都是显式的,我们称他们为显式锁。Java已经提供了synchronized,为什么还要使用JUC的锁呢?转载 2024-02-19 22:14:39 · 41 阅读 · 0 评论 -
并发编程-JUC-原子类
E:进行比较的值 (预期值)这个期望值是每次自旋的时候从V中读取出来,然后更新的时候再比较这个值和V中的值是否相等如果相等表示没有其它线程来修改,否则被修改过,继续自旋。主要存在三个缺陷:循环时间太长、只能保证一个共享变量原子操作、ABA问题。CAS其实就是执行一个函数:CAS(V,E,N)直到成功为止。V:要读写的内存地址。原创 2024-02-19 17:22:39 · 1140 阅读 · 0 评论 -
并发编程-Volatile
volatile可以保证多线程场景下变量的可见性和有序性。如果某变量用volatile修饰,则可以确保所有线程看到变量的值是一致的。可见性:保证此变量的修改对所有线程的可见性。有序性:禁止指令重排序优化,编译器和处理器在进行指令优化时,不能把在volatile变量操作(读/写)后面的语句放到其前面执行,也不能将volatile变量操作前面的语句放在其后执行。遵循了JMM的happens-before规则。改变线程本地内存中volatile变量副本的值;将改变后的副本的值从本地内存刷新到主内存。原创 2024-02-19 16:01:02 · 318 阅读 · 0 评论 -
并发编程-Synchronized
synchronized是Java提供的一个关键字,Synchronized可以保证并发程序的原子性,可见性,有序性。我们会把synchronized称为重量级锁。主要原因,是因为JDK1.6之前,synchronized是一个重量级锁相比于JUC的锁显得非常笨重,存在性能问题。JDK1.6及之后,Java对synchronized进行的了一系列优化,性能与JUC的锁不相上下。原创 2024-02-19 14:53:14 · 797 阅读 · 0 评论 -
并发编程-多线程并发特性
为了进一步加快程序的执行效率,在CPU和物理内存之间还有一个高速缓存的存在,这样程序的执行过程也就发生了改变,变成了程序在运行过程中,会将运算所需要的数据从主内存复制一份到CPU的高速缓存中,当CPU进行计算时就可以直接从高速缓存中读数据和写数据了,当运算结束再将数据刷新到主内存就可以了。在多线程的环境中如果线程1中发生了重排序,这个时候环境还没有初始化,但是init由于重排序的原因已经执行了语句2变为了true,这个时候线程2中使用的是没有初始化的环境,必然导致非常多的问题。2 多线程中的重排序。原创 2024-02-19 10:39:57 · 796 阅读 · 0 评论 -
并发编程-基础知识
这个过程存在一些问题,也就是说如果线程特别多,这个时候资源竞争激烈,这个时候上下文切换消耗的资源可能比任务执行还要多,所以实际开发中将线程的数量设置到一个合理的值,这样才能够提高应用 的运行效率。进程也是程序的一次执行过程,是系统运行程序的基本单位;线程:多线程之间堆空间与方法区是共享的,但每个线程的栈空间、程序计数器是独立的,线程消耗的资源比进程小的多。是进程中的一个执行单元,负责当前进程中任务的执行。一个进程在其执行过程中,会产生很多个线程。进程:有独立内存空间,每个进程中的数据空间都是独立的。原创 2024-02-19 08:54:05 · 827 阅读 · 0 评论