多线程:
什么是进程:
进程是运行中的程序,通俗的来讲就是我们用电脑操作系统打开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
-
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/121412.html