多线程
文章平均质量分 54
多线程相关学习
逍遥ovo
oxen and horses
展开
-
JUC(Java.util.concurrent)常见组件
ReentrantLockReentrantLock 和 synchronized 一样,也是一个可重入锁。ReentrantLock 使用方法import java.util.concurrent.locks.ReentrantLock;/**两个线程操作一个数*/public class MyReentrantLock { static int count; static ReentrantLock reentrantLock = new ReentrantLoc原创 2021-08-21 21:46:13 · 206 阅读 · 0 评论 -
Runnable 和 Callable 的区别
区别两个都是接口,但是 Runnable 方法中 run() 没有声明异常且没有返回值,而 Callable 中 call() 声明了异常且有返回值;(意味着使用 Runnable 需要自己处理异常)通过 Callable 创建线程需要一个辅助类 FutureTask 实例化对象来接收线程执行完毕后得到的结果,通过 FutureTask 中的 get 方法获取结果,如果线程阻塞,那么就会等待。而 Runnable 中如果想要得到结果,那么就需要定义一个属性来接收,并且需要手动等待线程结束。源码原创 2021-08-16 22:54:57 · 287 阅读 · 0 评论 -
synchronized 底层原理
synchronized 膨胀/降级 基本流程synchronized 不仅能够自动升级,还能自动降级!!!synchronized 不仅能够自动升级,还能自动降级!!!synchronized 不仅能够自动升级,还能自动降级!!!其他优化锁消除编译器/JVM 某个代码不涉及线程安全问题,而程序猿却给这个代码上了锁,那么就会把锁给自动去掉。锁消除与偏向锁的区别锁消除判定不涉及线程安全问题,把锁去掉。比如只有一个线程,还给这个线程加锁,那不是。。。那啥吗;偏向锁并不知道线程是否原创 2021-08-16 18:03:33 · 224 阅读 · 0 评论 -
CAS 浅析(原理、实现自旋锁、ABA的产生与解决)
什么是 CASCAS(compare and swap),比较与交换。如果普通的比较与交换 public void compareAndSwap(int num1, int num2) { if (num1 == 10) { num2 = 20; } }这个代码在 被编译成字节码文件等待一些列操作后,将在 CPU 上执行,而代码翻译成的指令不止一条,那就不能保证原子性。而在 CPU 中,能用一条指令能够成比较与交换。(伪代码)// 如果在这个位置(address) 的值原创 2021-08-16 11:35:48 · 737 阅读 · 0 评论 -
一个例子带你了解【死锁的原因】以及【解决的方法】
原因常见的场景一个线程一把锁正常情况下,一个线程只能有一把锁,当这个线程想上第二把锁的时候,要释放第一把锁,才能上第二把锁;而如果想要同时拥有两把锁,那么就是互相矛盾的。而 Java 中 synchronized 已经对这个问题进行了优化。在 synchronized 中,有一个变量专门记录了当前锁的数量(暂且用 count 来表示),也就是说,当线程上了锁 A 后,并不是真的给这个线程上锁,只是这个记录锁数量的变量 count++,如果再上一把锁 B,那么 count++,如果释放锁 B原创 2021-08-15 23:55:37 · 212 阅读 · 0 评论 -
可重入锁和不可重入锁
可重入锁与不可重入锁简单点理解可重入锁:如果同一个线程加两把锁,不会出现问题的叫 可重入锁;不可重入锁:而会出现问题的叫 不可重入锁。正常情况下,线程 A 加了锁 1,然后又要加锁 2,但是线程 A 要加锁 2 就必须释放锁 1,但是释放锁 1 就达不到沃目的(目的是加锁 1 和 锁 2),因此这里就出现了矛盾,也就是传说中的死锁。在 Java 中,synchronized 是可重入锁,synchronized中有一个变量记录了锁的数量,也就是说每当一个线程加一个锁,那么这个变量++,原创 2021-08-15 20:13:59 · 398 阅读 · 0 评论 -
公平锁与非公平锁
公平锁与非公平锁首先理解 公平 与 非公平 ,公平就是 不插队,非公平就是 插队。操作系统调度线程的方式就是 随机的,也就是说是 非公平锁。Java 中 synchronized 是 非公平锁。(自旋锁 也是 非公平锁)如果想实现非公平锁,那么就需要做出额外的处理:记录每个线程竞争锁的时间;按照时间对线程排序;根据排序来调度线程。...原创 2021-08-15 19:22:08 · 99 阅读 · 0 评论 -
重量级锁和轻量级锁(自旋锁)
重量级锁和轻量级锁重量级锁和轻量级锁 一般(一般一般一般) 类似于悲观锁和乐观锁,站在了不同的角度划分的。轻量级锁又叫自旋锁。重量级锁与轻量级锁是站在 工作量 的角度来划分的;而乐观锁和悲观锁则是站在 锁冲突概率 来划分的。重量级锁:我们知道,我们要进入一个同步、线程安全的方法时,是需要先获得这个方法的锁的,退出这个方法时,则会释放锁。如果获取不到这个锁的话,意味着有别的线程在执行这个方法,这时我们就会马上进入阻塞的状态,等待那个持有锁的线程释放锁,然后再把我们从阻塞的状态唤醒,我们再原创 2021-08-15 19:04:00 · 3105 阅读 · 0 评论 -
浅析读写锁
读写锁读写锁是一种特殊的锁,该锁把读操作和写操作分开了。普通的锁提供了两个操作:加锁和解锁;读写锁提供了三个操作:读加锁、写加锁和 解锁;在有的场景中,只有少部分线程进行写操作,而大多数线程进行读操作。读操作和写操作之间不需要保证原子性;读操作和读操作之间不需要保证原子性、内存可见性和禁止指令重排序;写操作和写操作需要保证原子性、内存可见性和禁止指令重排序。因此将这三个锁搭配使用,就可以提高效率比。几个线程之间只读数据,那么不用加锁;如果几个线程之间有一个线程写数据,其他线原创 2021-08-15 18:16:53 · 359 阅读 · 0 评论 -
乐观锁和悲观锁
乐观锁和悲观锁乐观锁和悲观锁都是一种锁策略,也就是如何设计锁。乐观锁:认为这个锁出现竞争的概率比较小(当前场景中,线程数目比较少,只是偶尔竞争一下锁)悲观锁:和乐观锁相反,悲观锁出现竞争的概率比较大(当前场景中,线程数目比较多,很可能涉及竞争锁)根据乐观锁和悲观锁的比较,可以得知乐观锁需要做的事情会少一些,而悲观锁需要做的事情更多一些。举个栗子A 和 B 两个人去爬山A 比较乐观,只带了一些必要的干粮和水B 比较悲观,害怕有什么始料不及的事发送,于是备足了干粮、水和应急设施等等。原创 2021-08-15 17:57:23 · 92 阅读 · 0 评论 -
线程不安全的原因以及解决方法
线程安全问题首先要了解使用多线程的原因,以 杀毒软件 为例。使用单线程想要执行 病毒查杀 和 清理垃圾,那么只能先执行 病毒查杀 和 清理垃圾 的其中一个,再执行另外一个。使用多线程可以 同时执行 清理垃圾 和 病毒查杀。但是问题随之而来,下边将解析多线程的安全问题。抢占式执行(线程安全根本原因)首先明确线程是 抢占式执行 的,也就是说,CPU 调度线程的时间是不确定的。还是以 病毒查杀 为例,可能 病毒查杀 这个线程执行到一半,就被调度出 CPU,然后执行 清理垃圾。多个线原创 2021-08-15 02:16:01 · 1741 阅读 · 0 评论 -
Thread 和 Runnable 的区别
今天在学习多线程的时候,了解了 创建线程的几种方式,然后就脑子发热,突然想到 Thread 和 Runnable 创建线程有什么区别吗?毕竟是长得都不一样。所以我就找了一些资料(CSDN 大佬们的文章)来看看,有了一些理解。明确一点:Runnable 和 Thread 本质上是没有区别的。区别如果非要说区别的话,那么就有一下几点Runnable 和 Thread 创建线程的方式不一样Runnable 是接口,Thread 是实体类,Thread 和 Runnable 的关系就是实体与实现.原创 2021-08-15 00:21:36 · 4487 阅读 · 0 评论 -
单例模式(饿汉模式和懒汉模式)
饿汉模式饿汉模式是线程安全的,不需要关键字来保证线程安全。class Singleton { // 期望 singleton 是一个单例, 也就是只有一个实例 private static final Singleton instance = new Singleton(); public static Singleton getInstance() { return instance; } private Singleton() {原创 2021-08-14 17:16:25 · 907 阅读 · 0 评论 -
懒汉设计模式使用 volatile 关键字和两个 if 判断的原因
懒汉设计模式代码class Singleton { // 3. 加 volatile 关键字 volatile private static Singleton instance = null; public static Singleton getInstance() { // 2. 外层判断 if (instance == null) { // 1. 内层加锁判断 synchronized (Singleton.class原创 2021-08-14 17:04:23 · 327 阅读 · 0 评论 -
wait() 和 sleep() 的区别
区别举个例子逍遥和老板去带客户去吃饭,逍遥中途被老板叫出去(wait 和 sleep 执行),逍遥出去后有两种再进入房间的方法当老板叫逍遥进去的时候逍遥进去(notify 执行);逍遥自己进去(sleep 结束)。虽然都进去房间了,但是效果是不一样的。逍遥自己进去万一老板和客户正在谈一些机密的事情,可能逍遥现场就凉了;但是如果是老板叫逍遥进去,那么说明逍遥是可以进去的。wait 是用于线程之间的通信,而 sleep 是用于线程阻塞的。唯一的相同点:都是让线程放弃执行一段时间。原创 2021-08-14 14:51:17 · 205 阅读 · 0 评论 -
创建线程的几种方式
目录继承 Thread 类创建线程实现 Runnable 接口创建线程Thread 匿名内部内创建线程Runnable 匿名内部类创建线程lambda 表达式创建线程继承 Thread 类创建线程class ThreadTest1 extends Thread { @Override public void run() { System.out.println("继承 Thread 后创建线程"); }}public class TestDemo2 {原创 2021-08-07 18:28:15 · 109 阅读 · 0 评论 -
进程和线程的区别
区别进程包含线程一个进程可以有一个或多个线程进程是资源分配的基本单位,线程是系统调度执行的基本单位也就是说,进程得到一部分资源后,一个和多个线程共享这部分资源进程与进程之间是相互独立的也就是说,进程 A 凉了,不影响进程 B。因为一个线程或多个线程共享一个进程的资源,所以一个线程挂了,可能会影响到整个进程,导致这个进程中的其他线程无法工作。...原创 2021-08-07 17:27:36 · 72 阅读 · 0 评论 -
初识进程,为后面多线程编程打基础!
目录什么是进程?为什么要引入进程?怎样概述进程?task struck 中存在哪些信息?什么是并行与并发?用户态与内核态什么是进程?概念:一个正在运行的程序。示例进程也叫做任务, 任务管理器中就存在很多进程。为什么要引入进程?希望能够执行多个任务,也就是多个进程。什么意思呢?也就是说,同一台电脑上,现在可以边打 LOL,一遍看直播,一遍聊天等等一系列的事。而在以前,只能打游戏,退出,看直播,退出,聊天,退出。(功能机了解一下)。充分利用 CPU 资源。随着 CPU 的发展,原创 2021-08-07 10:11:43 · 98 阅读 · 0 评论