多线程 简单了解使用

简介: 多线程 简单了解使用

多线程:

什么是进程:

进程是运行中的程序,通俗的来讲就是我们用电脑操作系统打开QQ这个程序,操作系统就会为我们为QQ这个进程分配地址内存。进程就是执行中的程序,它本身也有着产生,运行,消亡这几种状态

什么是线程:

线程就是进程的实例,一个进程有多个线程。

通俗的可以理解为:打开 QQ,可以同时打开多个聊天窗口,打开百度网盘可以同时下载多个任务

并发:

同一个时刻,多个任务交替执行,给人一种貌似同时的错觉,单核cpu实现的多任务就是并发

可以理解为似于:一个男人在开车的同时在打电话(当然这样是违法的)

并行:

同一时刻,多个任务同时执行,多核cpu可以实现并行

可以理解为:在同一时刻,一个男人在打电话,一个男人在开车

并发和并行也能同时存在:在同一时刻,一个男人一边打电话一边吃东西,一个男人在开车

创建线程的俩种方法:

1:继承Thread类 ,重写run方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rwbggBYR-1665058796179)(C:\Users\12926\AppData\Roaming\Typora\typora-user-images\1663382495569.png)]

class Cat extends Thread{
        int times = 0;
        @Override
        public void run() { //重写run方法,在这实现自己的业务逻辑
           while (true) {
               System.out.println("我是小猫咪"+ times++);
               System.out.println("" +Thread.currentThread().getName());
               try {
                   //1000毫秒= 1秒
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               if (times > 80) {
                   break;
               }
           }
 cat.start()  -->开启子线程
 cat.run()   --> 没有真正的启动线程,只是调用了run 方法 ,就会把run 方法执行完毕才向下执行 。
     这样 主线程会堵塞
        }

2:实现Runnable接口,重写run方法

3:实现Callable 接口,重写call 方法 (不常用)

Runnable 和 Thread 类的区别:

本质上没有区别,都要继承或者实现然后重写run 方法, 只不过Thread 类实现了 Runnable 接口。

实现Runnable 接口的方式,更加适合多个线程共享一个资源的情况,并且避免了Thread类的单继承的局限

建议使用Runnable接口

线程终止:

1:当线程完成以后,会自然退出

2:可以使用变量来控制run 方法 退出的方式停止线程,即通知方式

interrupt 中断线程,并没有真正的结束线程,一般用于中断正在的休眠线程

yield 让出的cpu,但不一定能够成功 (我就谦让一下,别当真啊。。。。。)

join 线程插队 (插队一定会成功!)。插队的线程一旦插队成功,就会执行完插入线程的所有的任务

线程的7种生命周期:

new 新建状态,

ready 准备状态, Running 运行状态 === Runnable 就绪状态 是否运行取决于调度器

Runnable 就绪状态 又分为ready 准备状态, Running 运行状态

ThreadWaiting 超时等待 join , sleep

Waiting 等待状态

Blocked 堵塞状态

Terminated 终止状态

Synchronized 关键字 -->是一种非公平锁

三个子线程同时去操作我们内存地址中的数据,线程1 抢到了锁之后,线程2和线程三就不能抢了,只能等待线程一执行完毕后释放锁,然后3个线程再去抢这把锁。注:(线程一还是可以再去抢到这把锁)所以说是非公平锁

只有拿到锁才能去执行,不然只能堵塞在这!!!

线程同步机制:在多线程编程种一些敏感数据不允许 被多个线程同时访问,此时就使用同步访问技术,保证数据在任何同一时刻,最多有一个线程访问,以保证数据的完整性

也可以理解为:,即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存进行操作,直到该线程完成操作,其它线程才能对该内存呢地址进行操作。

1:同步代码块
    syschronized(对象){  //得到对象的锁,才能操作同步代码
    //需要同步的代码
}
2:syschronized  还可以放在方法声明上,表示整个方法===为同步方法
    public syschronized void m (String name){
    //需要同步的代码
}
可以理解为:有一个去上厕所了,上厕所的时候将里面的门关上(上锁了),然后完事后在出来解锁,那么其它的小伙伴才能使用厕所

互斥锁

1:保证共享数据操作的完整性

2:每个对象都对应一个可称为“ 互斥锁” 的标记,这个标记用来保证在任意时刻,只能有一个线程访问该对象

3: 关键字synchronized 来与对象的互斥锁联系,当某个对象用synchronized 修饰时,表面该对象在任意时刻只能由一个线程访问。

4:同步会导致程序的执行效率变低!!!

5:同步方法(非静态的) 锁可以是this ,也可以是其他对象(要求是同一对象) Oject

6:同步方法(静态的) 的锁是当前类本身 类.class

public synchronized static void mi() {    锁是 当前类.class 
}
public  static void mi() {    锁是 当前类.class 
      synchronized ( 当前类.class ){
         //同步代码块
       }
}

线程死锁:

多个线程都占用了对方的锁资源,但还是都不肯想让,导致了死锁,在编程中一定要避免死锁的发生!

释放锁:

1:当前线程,同步代码块正常执行完成

2:当前线程,同步代码块种遇到break, return

3: 当前线程,同步代码块种出现未处理的Error 或者Exception 导致异常结束的

4:当前线程,同步代码块中执行了wait() 方法

不会释放锁:

1:当前线程,同步代码块中使用sleep(),yeild() 方法

2: 使用suspend() ,resume() 线程挂起 该方法不推荐

冒泡排序:

/**
 *     冒泡排序
 *     数组[24,69,80,57,13]
 *     第一轮排序:目标是把最大数放在最后
 *     第一次比较: 24,69,80,57,13
 *     第二次比较: 24,69,80,57,13
 *     第三次比较: 24,69,57,80,13
 *     第四次比较: 24,69,57,13,80
 *
 *     第二轮排序:目标是把最二大数放在倒数第二的位置
 *     第一次比较: 24,69,57,13,80
 *     第二次比较: 24,57,69,13,80
 *     第二次比较: 24,57,13,69,80
 *
 *     第三轮排序:目标是把最三大数放在倒数第三的位置
 *  *     第一次比较: 24,57,13,69,80
 *  *     第二次比较: 24,13,57,69,80
 *  
 *     第四轮排序:目标是把最四大数放在倒数第四的位置
 *  *     第一次比较: 13,24,57,69,80
 *

24,57,13,69,80

第三轮排序:目标是把最三大数放在倒数第三的位置
第一次比较: 24,57,13,69,80
第二次比较: 24,13,57,69,80
第四轮排序:目标是把最四大数放在倒数第四的位置
第一次比较: 13,24,57,69,80


目录
相关文章
|
缓存 Java Maven
如何在 Java 镜像构建过程中免重复下载依赖包
利用镜像构建缓存机制来加速 Java 镜像构建过程,免重复下载依赖包。
3629 0
如何在 Java 镜像构建过程中免重复下载依赖包
|
安全 开发者 iOS开发
如何获取安全获取苹果udid,imei
【8月更文挑战第12天】在iOS系统中,苹果出于隐私考量已禁止开发者直接获取设备UDID与IMEI。替代方案包括:1) **供应商标识符** (`[UIDevice currentDevice].identifierForVendor`),适用于同一开发者账号下的应用,可能随应用卸载重装而变化;2) **广告标识符** (`[ASIdentifierManager sharedManager].advertisingIdentifier`),用于广告追踪,用户可选择重置或限制。处理这些标识符时务必遵守苹果隐私政策。
417 1
|
分布式计算 Hadoop 大数据
【大数据】Hadoop下载安装及伪分布式集群搭建教程
【大数据】Hadoop下载安装及伪分布式集群搭建教程
555 0
|
网络协议 安全 Unix
socat神器解密:网络数据传输的利器
socat神器解密:网络数据传输的利器
876 1
|
测试技术
[蓝桥杯 2020 省 B1] 整除序列
[蓝桥杯 2020 省 B1] 整除序列
94 0
|
自然语言处理 算法 数据库
现代信息检索——索引构建
现代信息检索——索引构建
现代信息检索——索引构建
|
XML 负载均衡 Java
SpringCloud极简入门-客户端负载均衡-Feign
在前一章节,我们使用Ribbon作为客户端负载均衡完成了订单服务和用户服务的通信,其实我们可以发现,当我们通过RestTemplate调用其它服务时,所需要的参数须在请求的URL中进行拼接,如果参数少的话或许我们还可以忍受,一旦有多个参数的话,这时拼接请求字符串就会效率低下,并且显得好傻。而Feign的服务调用方式对于程序员来说更为友好,它基于Ribbon进行了封装,把一些负责的url和参数处理细节屏蔽起来,我们只需要简单编写Fiegn的客户端接口就可以像调用本地service去调用远程微服务。
350 0
Imageloader<8>-压缩图片
Imageloader<8>-压缩图片
163 0
|
机器学习/深度学习
MCMC-1|机器学习推导系列(十五)
MCMC-1|机器学习推导系列(十五)
441 0
MCMC-1|机器学习推导系列(十五)
|
JavaScript 前端开发