![](https://img-blog.csdnimg.cn/20201014180756916.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Java多线程
文章平均质量分 87
这个作者很懒~~
灰灰快醒醒
一枚大三字节跳动测试开发实习生。。
展开
-
CAS的超~详细介绍
ABA的问题:假设存在两个线程t1,t2.有一个共享变量num,初始值为A.接下来,线程t1想使用CAS把num变成Z,那么就需要先读取num的值,记录到oldNum变量中使用CAS判定当前num的值是否为A,如果为A,就要修改成Z.但是,在t1执行这两个操作之间,t2线程可能把num的值从A改成了B,又从B改成了A.线程t1的CAS期望num不变就修改.但是num的值已经被t2给改了.只不过又改成A了.这个时候t1究竟是否要更改num的值为Z呢?原创 2024-01-15 22:06:48 · 1260 阅读 · 22 评论 -
线程安全的集合类
原来的集合类,大部分都是线程不安全的.1.自己使用同步机制(Synchronized或者ReentrantLock),前面已经做过许多讨论了,这里不再展开.2.Collections.synchronizedList(new ArrayList); 3.使用CopyOnWriteArrayList.当我们往一个容器添加元素的时候,不直接往当前容器里添加,而是先将当前容器进行Copy,复制出一个新的容器,然后向新的容器里添加元素,添加完元素之后,再将原容器的引用指向新容器.一旦有线程修改值时,把顺序表复制一份原创 2024-01-19 12:48:42 · 1124 阅读 · 4 评论 -
JUC(java.util.concurrent)的常见类(多线程编程常用类)
3.CAS(原子类)4.Semaphore (也可以用于实现生产者消费者模型定义两个信号量:一个用来表示队列中有多少个可以消费的元素sem1,另一个用于表示队列中有多少个可放置新元素的空间sem2.生产:sem1.V(),sem2.P()消费:sem1.P(),sem2.V()原创 2024-01-17 17:00:24 · 1184 阅读 · 14 评论 -
synchronized原理
有些应用程序的代码中,用到了synchronized,但其实没有在多线程环境下.(例如StringBuffer)原创 2023-12-17 20:16:30 · 1370 阅读 · 6 评论 -
多线程案例-线程池
如果创建/销毁线程的频率进一步提高,此时线程的创建与销毁开销也就不能忽视了解决方案有两种:1.).纯用户态代码就比在内核内操作更安全更可控.协程是在用户代码中,基于线程封装过来的.本质是程序员在用户态中代码调度,而非内核调度器.2..用完了也不要释放而是以备下次使用以节省创建/销毁开销。原创 2023-12-14 14:09:52 · 1137 阅读 · 3 评论 -
等待和通知
由于线程是抢占式执行的,因此线程之间的执行的先后顺序难以预知但是实际开发中我们希望合理协调多个线程之间执行的先后顺序.完成这个协调工作,主要涉及到三个方法wait()/wait(long timeout):让当前线程进入准备状态.notify()/notifyAll():唤醒在当前对象上等待的线程.注意:wait,notify,notifyAll都是Object类的方法。原创 2023-12-08 23:10:16 · 1438 阅读 · 8 评论 -
volatile关键字
由上,可以发现输入的值是存入到了内存里面,而while哪里判断使用的flag一直都是从寄存器中读取的.因此输入的值并没有任何影响,那么有什么方法能够解决这种问题呢?前面我们讨论内存可见性时就说了`,直接访问工作内存(实际是CPU的寄存器或者CPU的缓存),速度非常快,但是可能出现数据不一致的情况.因为编译器发现,每次循环都要读取内存,开销太大,于是将读取内存的操作优化成读取寄存器的操作.禁止指令重排序,针对这个被volatile修饰的变量的的读写操作相关指令,是不可以重排序的.,这就解决上面的问题了。原创 2023-12-07 11:15:16 · 627 阅读 · 21 评论 -
多线程案例-定时器(附完整代码)
定时器是软件开发中的一个重要组件.类似于一个"闹钟".定时器是一种实际开发中非常常用的组件.比如网络通信种,如果对方500ms内没有返回数据,则断开尝试重连.比如一个Map,希望里面的某个key在3s之后过期(自动删除)类似于这样的场景就需要用到定时器.原创 2023-12-13 13:50:15 · 1051 阅读 · 11 评论 -
多线程案例-单例模式
单例 = 单个实例(对象)这一点在很多场景上都需要,一般就是一个对象持有(管理)大量数据时,比如JDBC中的DataSource实例只需要一个.单例模式具体的实现方式有很多.最常见的是"饿汉"和"懒汉"两种.类加载的同时,创建实例.懒汉模式-单线程版类加载的时候不创建实例.第一次使用的时候才创建实例.懒汉模式-多线程版 上面的懒汉模式是线程不安全的.举个例子:譬如这种情况,两次的if条件都符合,会创建两个实例,显然不符合规定.而这时就很容易想到使用synchronized来解原创 2023-12-09 15:40:53 · 1184 阅读 · 11 评论 -
线程安全的问题以及解决方案
我们把一段代码想象成一个房间,每个线程就是要进入这个房间的人.如果没有任何机制保证,A进入房间之后,还没有出来;B是不是也可以进入房间,打断A在房间中的隐私.这个就是不具备原子性的.原创 2023-12-03 10:07:22 · 1003 阅读 · 24 评论 -
常见的锁策略
定义:处理冲突的过程中,设计到不同的处理方式.特性:加锁开销大,加锁速度更慢,但是整个过程不容易出现问题.特性:加锁开销小,加锁速度更快,但可能引入一些其他问题(消耗更多cpu资源).锁的核心特性"原子性",这样的机制追根溯源是CPU这样的硬件设备提供的.注意:synchronized并不仅仅对mutex进行封装,在synchronized内部还进行了很多其它的工作.加锁机制重度依赖了OS提供的mutex加锁的开销更大,加锁速度更慢->重量级锁,一般就是悲观锁.加锁机制尽量不适用mutex,而是尽量在用户态原创 2023-12-17 18:14:38 · 1148 阅读 · 6 评论 -
synchronized关键字-监视器锁(monitor lock)
这就是我们上一篇中代码提到的加锁的主要方式,原创 2023-12-06 10:56:32 · 1273 阅读 · 18 评论 -
多线程案例-阻塞队列
阻塞队列是一种特殊的队列.也遵循"先进先出"的原则阻塞队列能是一种阻塞队列的一个典型应用场景就是"生产者消费者模型".这时一种非常典型的开发模型.原创 2023-12-11 20:56:22 · 994 阅读 · 24 评论 -
线程的状态
(指Thread对象创建好了,但未调用start方法在系统中创建线程)(也就是就绪状态:表示这个线程正在cpu上执行,或者准备就绪去cpu上执行)(由于锁竞争,引起的阻塞)(死等:比如join和wait)(指定时间的阻塞,到了一定时间后解除阻塞,使用sleep会进入该状态,超时间的join也会)(Thread对象仍然存在,但是系统内部中的线程已经执行完毕(已经销毁了))原创 2023-12-02 16:19:59 · 562 阅读 · 14 评论 -
线程的认识
在Thread t1 = new Thread() {...};中,写{}的意思是要定义一个新的类.与此同时,这个新的类,继承自Thread.此处{}中可以定义子类的属性和方法.原创 2023-11-23 14:51:58 · 248 阅读 · 5 评论 -
进程的认识
每个应用程序运行于现代操作系统之上时,.这种假象是通过抽象了一个进程的概念来完成的,进程可以说是计算机科学中最重要和最成功的概念之一.而现在所用的都是多任务操作系统.也就是同一时刻,可运行多个任务,这些正在运行中的程序,就可以称为任务,也叫进程程序的依次运行过程进程又是操作系统进行资源分配的基本单位。原创 2023-11-21 16:50:47 · 235 阅读 · 25 评论 -
Thread类及常见方法
Thread类是JVM用来管理线程的一个类,换句话说,每个线程都有一个唯一的Thread对象与之关联.用上一篇中的例子来看,每个执行流,也需要有一个对象来描述,而T,JVM也会将这些Thread对象组织起来,用于线程调度,线程管理.原创 2023-11-25 16:43:18 · 1126 阅读 · 17 评论