![](https://img-blog.csdnimg.cn/20190918140129601.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
并发多线程
多线程的知识以及例子
木十一的木马
这个作者很懒,什么都没留下…
展开
-
Lock锁
先看官方文档:实现类有可重入锁、读锁和写锁,可重入锁最常用。可重入锁,指的是以线程为单位,当一个线程获取对象锁之后,这个线程可以再次获取本对象上的锁,而其他的线程是不可以的。可以看到,ReentrantLock是lock接口的一个实现类,里面实现了可重入锁和公平锁非公平锁。公平锁:十分的公平,先来后到。非公平锁:十分不公平,可以插队。默认实现的是非公平锁。它的整个逻辑就是:加锁,在try里写业务代码,在finally里解锁。import java.util.concurrent.loc原创 2022-04-21 12:20:38 · 1151 阅读 · 0 评论 -
volatile 关键字(详细讲解)
我认为volatile 关键字有两个作用:第一个,它是可以去保证多线程环境下对于共享变量的可见性。第二个,是可以通过增加内存屏障去防止多个指令之间的一个重排序。我理解的可见性呢,是指当一个线程对于共享变量的修改,其他线程可以立刻看到修改之后的一个值。其实这个可见性问题我认为本质上是由几方面造成的:首先是CPU层面的告诉缓存,在CPU里面设计了三级缓存去解决CPU运算效率和内存IO效率的问题,但是他也带来了就是缓存一致性问题,而在多线程并行执行的情况下,缓存一致性就会导致可见性问题。所以对于增加原创 2022-04-16 16:34:07 · 956 阅读 · 0 评论 -
抗并发的两种策略
一种是数据库操作:做分库策略,另外,为了保证它的稳定性,我们可以做主从容灾。另一种是加缓存:可以把那些读的频率高且不常修改的数据预先存到缓存中,下次直接去缓存中查找,而频繁变动的数据不适合缓存我们就使用分库操作。对于那些访问频率特别高而且变动频率很低的,将他们放入缓存,比如Redis数据库;对那些经常需要变动的数据,没办法缓存,我们在数据库确实一台扛不住,我们就加了多台数据库进行了分库策略。分库策略:比如说数据库中有一百个表,我们在每台服务器上存放20个表,更新的时候去对应的服务器上进行操作。每台服原创 2022-03-19 13:28:38 · 811 阅读 · 0 评论 -
synchronized锁
对于普通方法:锁是当前实例对象。对于静态方法:锁是当前类的Class对象。也叫类锁。对于方法块:锁是Synchronized括号里配置的对象。也叫对象锁。当我们不加锁的时候,两个线程互不影响,说不定谁先执行Person类:public class Person { public void m1(String s){ System.out.println(s + "开始执行m1"); try { Thread.sleep(3000);原创 2022-03-19 13:04:12 · 783 阅读 · 0 评论 -
线程通信:生产者消费者问题
1.应用场景:假设仓库中只能放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中的产品取走。如果仓库中没有产品,则生产者将产品放入仓库,否则停止生产并等待,知道仓库中的产品被消费者取走为止。如果仓库中放有产品,则消费者将产品取走消费,否则停止消费并等待,知道仓库中再次放入产品为止。2.问题分析:这是一个线程同步问题,生产者和消费者共享同一个资源,并且生产者和消费者之间相互依赖,互为条件。对于生产者,没有生产产品之前,要通知消费者等待,而生产了产品之后,又需要通知消费者消费。对于消费者,在原创 2021-11-19 18:00:53 · 245 阅读 · 3 评论 -
死锁的例子
什么是死锁?多个线程互相抱着对方的资源,然后形成僵持产生死锁的四个必要条件:(1)互斥条件:一个资源每次只能被一个进程使用(2)请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放(3)不剥夺条件:进程已获得的资源,在未使用之前,不能强行剥夺(4)循环等待条件:若干进程之间形成一种头尾相连的循环等待资源关系上面列出的四个必要条件,我们只要想办法破其中任意或多个条件,就可以避免死锁的产生/** * @author DB * @title: DeadLock * @proje原创 2021-11-14 22:54:40 · 606 阅读 · 0 评论 -
线程安全的三大不安全案例以及解决方法
1.不安全的买票:多个线程去抢票,如果不线程同步,那么就会出现问题,具体看代码:/** * @author DB * @title: ThreadAnQuan * @projectName XianCheng * @description: 买票案例 * @date 2021/11/13 16:53 */public class ThreadAnQuan1 { public static void main(String[] args) { BuyTicket bu原创 2021-11-14 19:14:00 · 2812 阅读 · 0 评论 -
并发与线程同步
1.什么是并发?多个进程访问同一个对象2.线程同步:线程同步的形成条件:队列 + 锁处理多线程问题时,多个线程访问同一个对象,并且某些线程还想修改该对象。这时候我们就需要线程同步。线程同步其实时一种等待机制,多个需要同时访问此对象的线程进入这个对象的等待池形成队列,等待前面线程执行完毕,下一个线程再使用。由于同一进程的多个线程共享同一块存储空间,在带来方便的同时,也带来了访问冲突的问题,为了保证数据在方法中被访问时的正确性,在访问时加入了锁机制 synchronized ,当一个线程获得对象的锁,原创 2021-11-12 00:25:07 · 743 阅读 · 0 评论 -
多线程-守护线程
守护线程(daemon):线程分为用户线程(如main线程)和守护线程;虚拟机必须确保用户线程执行完毕,而不会等待守护线程执行完毕;守护线程有:记录操作日志的线程、监控内存的线程、垃圾回收等待…setDaemon(boolean r) 参数是个boolean类型的,当参数为true的时候即为守护线程,默认是false,用户线程/** * @author DB * @title: ThreadDaemon * @projectName XianCheng * @description: 测试原创 2021-11-09 16:35:10 · 1145 阅读 · 0 评论 -
线程优先级
Java提供了一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定应该调用哪个来执行。线程的优先级用数字表示,范围从1~10Thread.MIN_PRIORITY = 1;Thread.MAX_PRIORITY=10;Thread.NORM_PRIORITY=5;(默认的)使用一下方法改变和获取优先级:setPriority() 、getPriority()/** * @author DB * @title: ThreadPriority * @project原创 2021-11-09 16:06:53 · 230 阅读 · 0 评论 -
线程的五大状态及转换
一.线程的五大状态:创建状态、就绪状态、运行状态、阻塞状态、死亡状态1**.创建状态**(新生状态):new 线程对象Thread t = new Thread();线程对象一旦创建,就进入了新生状态。2.就绪状态:new出来以后,当调用start()方法,线程就会立即进入就绪状态,但不意味着立即调度执行。3.运行状态:处于就绪状态的线程,经过CPU调度就会进入运行状态,线程才会真正执行线程体的代码块。4**.阻塞状态**:当调用sleep、wait或同步锁定时,线程进入阻塞状态,就是代码块不往下原创 2021-11-06 18:06:51 · 4107 阅读 · 0 评论 -
Lambda表达式
λ是希腊字母表中排序第11位的字母,英文名为Lambda,Lambda表达式质属于函数式编程的概念。JDK8后出现的Lambda表达式1.为什么要使用Lambda表达式?(1)避免匿名内部类定义过多(2)可以使代码看起来很简洁(3)去掉了一堆没有意义的代码,只留下核心的逻辑2.函数式接口:理解函数式接口是学习Lambda表达式的关键所在;函数接口的定义:任何接口只要只包含一个方法,那么它就是函数式接口。例如:public interface Runnable{ public abstract原创 2021-11-05 16:35:19 · 77 阅读 · 0 评论 -
理解静态代理
举一个结婚的例子来理解一下静态代理,静态代理分真实对象和代理对象,而我就是真实对象,婚庆公司是代理对象。调用的是代理对象的方法却能执行真实对象的。public class Proxy { public static void main(String[] args) { You you = new You(); WeddingCompany weddingCompany = new WeddingCompany(you); weddingCompany原创 2021-11-04 21:11:47 · 79 阅读 · 0 评论 -
使用多线程进行网图下载
1.下载commons-io-2.2.jar,放进项目中public class LianXiThread extends Thread{ private String url; private String name; //定义构造方法 public LianXiThread(String url, String name){ this.url = url; this.name = name; } //重写run()方法 @Ov原创 2021-11-03 23:23:21 · 99 阅读 · 0 评论 -
synchronized锁
1.修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码快前要获得 给定对象 的锁。public class ThreadCount implements Runnable{ private static int count = 100; @Override public void run() { while (count > 1) { cal(); } } private void cal() {原创 2021-10-30 19:34:45 · 67 阅读 · 0 评论 -
初学线程安全
当多线程同时对一个全局变量进行写的操作的时候。可能会受到其他线程的干扰,就会发生线程安全性问题。在多个线程对一个变量做竞争的时候就会大概率的发生线程安全问题。public class ThreadCount implements Runnable{ private static int count = 100; @Override public void run() { //死循环是为了保证线程一直在运行状态 while (true){原创 2021-10-30 17:27:52 · 73 阅读 · 0 评论 -
多线程的创建方式
多线程的创建有七种方式:(1)继承Thread类创建线程(2)实现Runnable接口创建线程(3)使用匿名内部类的形式创建线程(4)使用lambda表达式创建线程(5)使用Callable和Future创建线程(6)使用线程池例如用Executor框架(7)spring 的@Async异步注解1.继承Thread类创建public class ThreadDemo extends Thread{ //程序执行的代码就在run()方法中 @Override pub原创 2021-10-29 16:17:42 · 3139 阅读 · 0 评论 -
关于进程、线程
进程是资源分配的最小单位,线程是程序执行的最小单位。计算机在执行程序的时候,会为程序创建相应的进程,进行资源分配时,是以进程为单位进行相应的的分配,每个进程都有相应的线程,在执行程序时,实际上执行的是一系列线程。(1)CPU从硬盘上读取一段代码到内存中,该执行的实例就叫进程;(2)一个程序如果被CPU多次读取到内存中,则会成为多个独立的进程;(3)在一个进程中可以有多个不同的线程同时执行。CPU调度算法:先把前一个任务的CPU上下文保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再原创 2021-10-29 14:40:01 · 75 阅读 · 0 评论 -
串行,并发,并行
串行Sequential:先做任务A,完成后再做任务B,然后再做任务所有的任务逐个完成,原创 2021-10-16 22:52:42 · 133 阅读 · 0 评论 -
什么是进程?什么是线程?
一个程序进入内存被称为进程,一个可执行文件可以有多个进程。一个进程内部有多个任务并发执行的需求(比如一边计算,一边接受网络数据,一边刷新页面),这样的话可以使用多进程,但是问题也多,最严重的问题是其中一个进程可以轻易的搞死其他进程。所以出现了线程的概念。线程:共享空间,不共享计算。线程就是一段段的代码进程和线程的区别:进程是静态的概念:程序进入内存,分配对应的资源;进程进入内存,同时产生一个主线程。线程是动态的概念:是可执行的动态单元(任务)一个ALU同一时间只能执行一个线程。线程和CPU是一一原创 2021-10-08 21:02:17 · 918 阅读 · 0 评论 -
操作系统-进程控制块PCB
1.进程实体包括:程序段、数据段、进程控制块PCB;2.进程控制块是操作系统中最重要的数据结构。PCB是用来记录进程信息的。比如说当CPU执行某程序的时候,当停止执行一段时间后,重新执行的时候如何让他从断的那里开始?这里我们需要用到PC,PCB是:Process Control Block;PC是:Program CounterPC指向的是下一条指令的值,我们可以将断的位置的PC存到PCB中,那么当重新开始执行的时候就会接着上次的进行执行。3.PC是硬件,叫程序计数器;PC在IR中;PCB在内存中原创 2021-09-10 20:59:20 · 2744 阅读 · 0 评论 -
操作系统:进程
1.前趋图的概念:前趋图是一个有向无循环图,图中的每个结点可用于表示一条语句、一个程序段或者进程,结点间的有向边表示在两结点之间存在的偏序或前趋关系“➡”;eg:p1➡p2:称p1是p2的前趋;什么是全序?什么是偏序?全序:比如一个自然数的集合,从其中任意拿出两个数就可以进行比较;偏序:有的可以进行比较,有的不可以进行比较;比如结点2,3就不能进行比较。2.程序的顺序执行和并发执行:顺序执行: 程序在执行时,必须按照某种先后顺序逐个执行,仅当前一操作执行完后,才能执行下一操作;顺序原创 2021-09-07 21:58:03 · 516 阅读 · 0 评论