Java多线程
文章平均质量分 94
多线程的学习
tao滔不绝
22级大学生,用写博客的方式记录学习,欢迎大家阅读
展开
-
计算机是如何工作的(简单介绍)
1、CPU要执行的指令,是在内存中的(冯诺依曼体系结构,基本设定,执行单元(CPU)和存储单元(内存)是分开的,让执行单元和存储单元解耦合)2、CPU要想执行指令,就需要先取指令,再解析指令,然后才能执行指令。3、取指令需要从内存中读取指令到CPU的寄存器中,取指令的操作,其实是非常耗时的(读取内存操作相对于CPU执行计算,开销要大很多)。因此CPU中通过“缓存”、“流水线”等技术,来优化这里的效率。原创 2023-11-17 21:41:56 · 1496 阅读 · 86 评论 -
多线程Thread(初阶一:认识线程)
网站 / Web开发,是一种服务器程序,我们知道,一个网站服务器在同一时刻,会受到很多请求,针对这些请求,会创建进程,一个请求创建一个进程,创建完一个进程,又要销毁这个进程,这意味着这个网站服务器要频繁的创建和释放资源,这个操作开销是比较大的,而从系统分配一个内存,并非是件容易的事,一般来说,申请内存的时候需要指定一个大小,系统内部就要把各自大小的空闲内存,通过一定的数据结构,给组织起来,实际申请的时候,就需要去这样的空间中进行查找,找到一个大小合适的空闲内存,进行分配。不直接把硬件给干烧了,所以,原创 2023-11-19 09:03:36 · 770 阅读 · 89 评论 -
多线程Thread(初阶二:Thread类及常⻅⽅法)
最后一个线程组的概念是java的概念,和系统中的线程组不一样,不是同一个东西。第一个和第二个构造方法在初阶一有介绍,第三是创建一个线程,并且可以给这个线程命名,并不是它默认的Thread-0 / 1 / 2.....,第四个也是可以给线程对象命名,不过是使用接口的方法。执行效果:两个线程:上面两种的两种创建线程方式都可以。执行效果:我们创建的线程如果不起名字,默认是Thread-0 1 2 3....,给不同线程起不同名字,对于线程的执行,没啥影响,主要是为了方便调试;原创 2023-11-24 12:40:18 · 351 阅读 · 8 评论 -
多线程Thread(初阶三:线程的状态及线程安全)
暂时就画这么多,因为线程并发的执行结果个数是无数的,并不是简单的排列组合就能穷举出来,因为并发的原因,可能 t1 线程它执行了两次,才执行一次 t2 线程,也可能更多,或者 t2 执行的次数更多,t1 线程只执行一次。这时,t1 和 t2自增的时候,就可能拿的是同一个值,这两线程的其中一个自增后,没放回内存中,另一个线程就又拿了,这肯定是不符合我们预期的。某个代码,它单个线程执行,不会产生bug,但是多个线程执行,就会产生bug,这个情况就成为 “线程不安全”,或者 “存在线程安全问题”。原创 2023-11-24 15:07:37 · 489 阅读 · 28 评论 -
多线程(初阶四:synchronized关键字)
它的加锁和解锁和java是不同的,在C++里,加锁:locker.lock() 解锁:locker.unlock(),他们的加锁和解锁是分开执行的,C++这种写法可能导致程序猿忘记调用unlock,或者unlock没执行到,这时就会产生很严重的bug,没解锁,其他加锁用和它一样对象的线程,就会一直等待。给加锁的对象是任意的引用类型都可以的,我们也可以随便起个对象,但是要记住加锁的核心,两个线程之间加锁的对象,是否是同一个对象,是同一个对象,就会产生竞争,反之则不会。具体还是要看代码怎么写。原创 2023-11-25 16:55:33 · 467 阅读 · 28 评论 -
多线程(初阶五:wait和notify)
但是如果ATM机里面没有钱时,A线程就不能完成取钱这个操作,它会退出ATM机,但退出后呢,它因为没有完成取钱的操作,就会想继续进去ATM里面,完成取钱这个操作,就会继续和其他线程进行锁竞争,因为A线程拿到了锁,处于RUNNABLE状态,其他线程因为阻塞,处于BLOCKED状态,需要被系统唤醒后,才能去竞争锁,但是线程A呢,不用唤醒就能去竞争锁,后面又被A线程拿到锁的可能性还是很大的(类似近水楼台先得月)。同时,有线程wait了,也必须有其他线程notify来释放这个wait,不然这个wait就会一直阻塞。原创 2023-12-01 21:56:32 · 353 阅读 · 25 评论 -
多线程(初阶六:单例模式)
单例模式是一种设计模式,其中设计模式是软性的规定,与它关联的框架是硬性的规定,这些都是大佬已经设计好了的,即使是代码写的不是很好的菜鸡,按照这种模式也能写出还行的代码。类似象棋中的棋谱,即使你是新手,但按着棋谱走,你的棋力也不会太差。单例 = 单个实例(对象);某个类,在一个线程中,只应该创建一个对象(原则上不应该有多个),这时就使用单例模式,就可以对我们的代码进行一个更严格的校验和检查。那么,怎么保证这一个对象唯一呢?原创 2023-12-01 21:56:45 · 680 阅读 · 36 评论 -
多线程(初阶七:阻塞队列和生产者消费者模型)
首先,我们都知道,队列是先进先出的一种数据结构,而阻塞队列,是基于队列,做了一些扩展,在多线程有就非常有意义了阻塞队列的特性:(1)是线程安全的(2)具有阻塞的特性①当队列满了,这时不能往队列里放数据,就会阻塞等待,等队列的数据出队列后,这时队列没满,才能放数据。②当队列空了,这时不能拿队列里的数据,就会阻塞等待,等有数据如队列了,这时队列不为空,才能拿数据。这里,阻塞队列的用处非常大,基于阻塞队列的功能,就可以实现 “生产者消费者模型”。原创 2023-12-03 17:35:23 · 2762 阅读 · 59 评论 -
多线程(初阶八:计时器Timer)
在标准库中,提供了Timer类,Timer类的核心方法是schedule,里面包含两个参数,一个是要执行的任务代码,一个是设置多久之后执行这个任务代码的时间。Timer内置了线程(前台线程)@Override}, 3000);原创 2023-12-06 10:36:34 · 1280 阅读 · 44 评论 -
多线程(初阶九:线程池)
目录一、线程池的由来二、线程池的简单介绍1、ThreadPoolExecutor类(1)核心线程数和最大线程数:(2)保持存活时间和存活时间的单位(3)放任务的队列(4)线程工厂(5)拒绝策略2、Executors类3、讨论线程池中创建多少线程合适三、线程池的模拟实现(1)阻塞队列:存放要执行的任务(2)submit方法:添加任务的方法,任务添加到队列中(3)构造方法:指定创建多少个线程,线程在这个构造方法中都创建好了(4)存放线程的链表:每创建一个线程都放进链表中,这样也能让我们找到某个线程(5)最终代码原创 2023-12-08 19:27:05 · 416 阅读 · 48 评论 -
多线程(进阶一:锁策略)
一、乐观锁和悲观锁二、轻量级锁和重量级锁三、自旋锁和挂起等待锁四、普通互斥锁和读写锁五、公平锁和非公平锁六、可重入锁和不可重入锁七、synchronized和Linux的mutex锁的简单比较八、synchronized的自适应。原创 2023-12-09 11:07:34 · 377 阅读 · 19 评论 -
多线程(进阶二:CAS)
字面意思是“比较和交换”;一个CAS涉及到以下操作,有两个寄存器:A,SwapB,还有内存的值:AddressC。先判断寄存器A是否和AddressC的值相同,相同,SwapB的值和AddressC的值进行交换,返回成功操作,否则返回失败操作。这里的交换值我们也可以理解成赋值操作,因为寄存器中的值我们不关心,用完就丢掉了,只关心内存中的值。原创 2023-12-10 12:03:06 · 2597 阅读 · 54 评论 -
多线程(进阶三:JUC)
一、Callable接口二、reentrantLock三、原子类四、线程池五、信号量 Semaphore六、CountDownLatch。原创 2024-02-02 22:40:55 · 1450 阅读 · 47 评论 -
多线程(进阶四:线程安全的集合类)
大部分集合类都是线程不安全的,Vector,Stack,Hashtable是线程安全的,但不建议使用,因为无论什么情况都要加锁,甚至单线程也是,这样就很不合理;并且这几个集合类官方已经不推荐使用了,可能在未来的版本中就被删掉了。下面介绍一些线程不安全的集合类。原创 2024-03-02 21:27:09 · 1102 阅读 · 25 评论