栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

多线程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多线程

 

多线程:多条流程同时进行的技术

 

方式1:

调用start()方法也是告诉CPU 我们是以线程的形式进行操作的

如果直接调用run方法

那么CPU就默认你是单线程进行的  那么这里打印子永远快于父

 Thread t=new MyThread();

这是一种多态的形式:只要是继承于Thread类的所有子类都可以通过它进行new出对象

这里new出来了MyThread类对象

子线程和父线程同时进行:

打印时:有可能子线程快于父线程 也可能父快于子

 

 

 第二点演示:

把主线程放置前面时  会造成一个单线程的效果

 切换为中文:

 

 

 为什么把MyRunnable的任务对象交给Thread处理?

因为MyRunnable实现了Runnable接口

并且用Runnable  new了一个新对象

target这个对象引用是属于类 Runnable的

由于Thread的参数是Runnable类型  因此可以把target这个任务对象交给Thread处理

Thread t =new Thread(target);

new出一个新对象  这个对象引用是t

 t.start()表示调用子线程开始执行

同时父线程也开始执行  那么就形成了多线程

 

 

并且多了一层对象的包装

注意:

我们改变了一下形式:

 new后面的那一块都是属于对象target的

之后把target给第4处

之后调用start()方法  它会启动run方法 那么子线程启动

之后继续执行主线程循环

 1.

2.

 3.

 4.

 以上这四个线程是同时执行的

存在的问题:

 

 

 由于这里是泛型 我们可以把泛型定义为String 那么返回类型就是String

并且在作用时也是String类型

这里的try catch语句主要是为了避免在它发生异常的时候 我们还是进行

这里用这个语句是为了在异常的时候我们能够发现并且及时阻止 执行catch语句

由结果可知:我们这里是可以返回结果的 

 

 

 

 t.start();这个调用执行的是run()方法

调用之后 并且主线程也随着调用执行

这三个线程的执行调用速度是不可预知先后顺序的

我们可以知道Thread是MyThread的父类

那么在子类的构造器中  我们可以通过super调用父类的有参构造器参数name

 用super把name送给父类的有参构造器   

那么当我们new对象的时候传参 

即:Thread t1=new Mythread("1号");  这是多态的书写形式   t1此时被命名

 重新定义名字

 

 currentThread表示谁调用它  它就代表哪一个线程

 线程安全问题:

 

多线程同时发生

 

 先模拟安全问题:

 

线程安全如何解决?

 

 当一个线程进来访问完毕之后 锁才可以解开

 加锁的方式有很多种:

1. 

如何上锁呢?全部选种  ctrl+alt+t键 选择第九个

这个锁必须满足锁的唯一性:

 那么我们可以用字符串常量  因为它是存在于字符串常量池中的

所以它是唯一的  无论是对于 小明还是小红

 但是这把锁是不行的  因为不只有小明和小红一家人去取钱

如图 他们会把小黑小白的账户也锁着了

因此我们用this来作为锁  this==acc

这个是代表账户 每一家人的账户是不同的 因此this代表的账户也是不同的

因此锁也是不相同的  

 

类Account是唯一的  

所有线程都是通过这个类来调用的  假设有100个线程 那么只有一个线程可以进来

访问完毕之后才会开锁 

 

 2.同步方法

 

 3.

Lock锁:它能更自由的执行何时上锁 何时解锁 

final修饰的变量只能被初始化一次

finally代码块中的语句是一定会被执行的

 重点:

线程池:

原理:

举个例子:

只有三个线程在进行工作

当处理完手头工作之后它又可以执行后面继续处理后面的任务

这样就极高的提升了工作效率

 第一种方法最重要:

 

 参数一:核心线程就是不会死亡的线程  在执行之后依旧存活完好

参数二:最大线程数就是包括核心线程和临时线程的最大数量

参数三:临时线程就是用完可能就消失的线程

参数四:指定的是临时线程的指定存活时间

参数五:假设你最大线程数为10 当第11个任务出现的时候 

你就要把这第11个放到任务队列中进行缓存着的地方

 参数六:帮我们创建线程的

参数七:假设你最大线程数为10 当第11个任务出现的时候  你要给出一个解决策略  抛出一个异常

配置一个拒绝策略

举个例子:

有一个kTV  外面有10个座位这十个座位可以坐客人叫做指定的任务队列

我们招聘3个长期工这叫做核心线程  七个临时工这叫做临时线程

假设临时工用2天 这个2天就是参数三

参数六就是招聘员工的人力资源师

当外面十个座位坐满并且我们招聘的员工都在忙的时候来人了

那么就是执行参数七一样的策略

 

 这个get方法要等到f1这个执行完之后才可以进行执行

 构建线程池的常用API:

 

 OOM表示是内存溢出的意思

ctrl+alt+delete打开任务管理器

 

定时器: 

 

 delay表示延迟多久执行第一次

当第一次执行完之后  就没有delay延迟了

period表示再每隔多长时间再执行一次  也就是周期

task表示执行的任务

实现定时器:

 ok:这个delay为3秒

表示延迟3秒之后执行run方法

到这之后 延迟delay就不再作用了  

第一次执行完之后  再每一次间隔period时间段再执行一次run方法

也就是说  一开始先延迟3秒再调用run方法

之后再每一次周期间隔2秒调用一次run方法  中间没有延迟

 

 1.但是这是单线程定时器 当执行一个任务时  后面的任务就要进行等待 

 2.一个任务一异常其他所有的任务都会挂掉

程序挂掉的过程:

因为这是单线程  不太负责任  当出现异常的时候 

它不会进行处理  而是直接把它抛给JVM虚拟机

JVM非常牛逼  直接会把整个程序给挂掉

 因此我们引入了:

我们通常就用下面这个定时器

因为这个定时器内部有线程池

因此即使第一个任务没有执行完 第二个任务也会同时执行 不会受到影响

并且当一个任务出错的时候  其他不会受到影响

 BBB执行一次  10/0是错误 直接挂掉

原理:

但是CCC不会挂掉  因为这是线程池  不是单线程

他不会把这个异常交给JVM虚拟机 它会自己进行处理

因为它是线程池 也不是单线程  大不了把那个异常的任务线程给挂掉就行

不会把整个程序给挂掉

因此程序不会挂掉

总而言之:

线程池牛逼!!!!

 

 多线程是并发和并行同时进行的

 

 线程的生命周期:

 

 notify表示唤醒操作

当你等待时 

即是Waiting或Timed Waiting时 我们必须要notify才可以即刻唤醒它  否则就要持续等待

 

 

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/592433.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号