1、多任务:eg:一边吃饭,一边玩手机
2、多线程:
一、程序.进程.线程
二、线程的创建
自己写的线程都在main函数里面,垃圾回收线程叫做守护线程是jvm给的
1、创建线程实例:
(1)注意:线程开启不一定立即执行,由CPU调度:
(2)联系thread,实现多线程同步下载
(3)线程创建方法二:runnable接口:调用start之后也是交替执行的
小结:继承thread类:(1)子类继承thread类具备多线程能力;(2)启动线程:子类对象.start();(3)不建议使用:避免oop单继承局限性
实现Runnable接口:(1)实现接口Runnable具有多线程能力;(2)启动线程:出入目标对象+Thread对象.start();(3)推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用
(4)避免单继承局限性,灵活方便,方便同一个对象被多个线程使用实例:
买火车票的例子:写了sleep的时候,都拿到票了,但是拿到重复的,线程不安全,数据紊乱
没写sleep的时候,有的拿到,有的没拿到(小明把十张票拿完了),因为是cpu调度的,速度太快了
(5)龟兔赛跑
每次输出的都是兔子赢
模拟兔子休息:乌龟赢了
3、实现callable接口(了解即可)
二、lamda表达式
函数式接口:
使用静态内部类,实现
使用局部内部类:
使用匿名内部类:
使用lamda表达式
简化:(1)lamda表达式只能有一行代码的情况下才能简化成为一行,如果有多行必须有代码块包裹(2)前提是函数式接口(只能有一个方法)(3)多个参数也可以去掉参数类型,要去掉就都去掉
三、静态代理模式
1、线程状态
2、线程方法:
3、停止线程:(1)建议线程正常停止---利用次数,不建议死循环;(2)建议使用标志位---设置一个标志位;(3)不要使用stop或者destroy等过时或者JDK不建议使用的方法
标志位强制停止的方法:
四、线程休眠
五、线程礼让:让当前正在执行的线程停止,但不阻塞
六、Join:合并线程,待此线程执行完成后,再执行其他线程,其他线程阻塞,插队
七、线程状态观测
线程只能启动一次,不能启动两次,死亡之后的线程,不能再次启动
八、线程的优先级:线程的优先级高,不一定先执行,但是给的资源会多一些,权重会高一些
主线程是一个默认的优先级,不会改变
觉得这个线程重要,可以设置优先级,但是不一定优先级高的会先执行
九、守护线程
守护线程在程序结束之后还会执行一会儿,比如这个例子,上帝这个实例在程序结束之后仍然会打印几个线程的输出,平时不用管守护线程,比如gc是看不到的
十、线程同步机制
同步:多个线程操作同一个资源,会出现问题
并发:同一个对象被多个线程同时操作
线程同步:
1、队列和锁:线程同步就是用到这两个特性,保证了线程的安全性
队列:排队
锁:
十一、线程不安全实例:每个线程都在自己的动作内存交互,内存控制不当会造成数据不一致
1、线程不安全有负数:此时没有排队,都会去取
2、不安全的取钱
此时的thread可以取代this
此时会打印说一个人取不了
延时后(sleep会方法问题的发生性):此时会打印出来余额变成了负数
3、线程不安全的集合:
(1)ArrayList:结果会变少,原因是两个元素放到了同一个位置,会出现被覆盖的情况
十二、同步方法和同步块
eg:将上面的例子使用同步的方法来实现,结果不会出现负数
同步方法保障了线程的安全性
同步方法默认锁的是this对象,synchronized默认同步的是本身,这种场景下解决不来的,就需要使用同步块的概念,下面的例子直接使用同步,还是会出现错误,剩余为负数的情况,但是使用同步块之后,就不会出现这种情况:锁的对象就是变化的量,需要增删改的对象,比如这个例子,改变的不是银行,所以使用同步会出现问题,使用同步块,控制银行卡(改变的量)即可
十三、死锁
多个线程互相抱走吧对方需要的资源,然后形成僵持
结果,:导致了程序卡死
解决方式:把同步放到代码块外面,不要两个人同时去抱一把锁:程序卡了一下,但是正常进行了
死锁的避免条件
十四:Lock锁:显示定义同步锁
(1)多个对象操作同一个资源,出现不安全的情况,产生了负数
(2)定义lock锁:结果一个一个产生,且全部拿到票了,不会出现负数这种异常情况
十五、生产者消费者问题
1、线程通信:
2、解决方式:
(1)管程法:利用缓冲区来解决
(2)信号灯法(标志位)
十六、管程法
结果:生产了消费,消费了生产……
十七、信号灯法:通过标志位解决
结果:生产者生产什么,观众观看什么
十八、线程池
结果:线程池都跑起来了
十九、线程总结: