线程简介
多任务
同一时间做了一件事情,交替很快,宏观上是同时。(边玩手机边吃饭
多线程
一个车道堵住,多开车道

一个进程可以有多个线程,比如视频里面同时有声音,弹幕,图像
程序是一个静态概念。进程是一个动态概念。线程是CPU调度和执行的单位。
- 线程是独立的执行路径。
- 对同一个资源进行操作时,要加入并发控制。
- 数据同步问题
- main()是主线程,系统的入口
线程创建
继承ThreadClass类:
*重写run方法,调用start开启线程。线程开启不是立即执行,由CPU进行调度。并行交替执行。
*多线程下载图片:理想路径t1-t2-t3。最终路径 3-1-2 同时下载的。看谁小谁先下完。并不是顺序执行。(有参数)
*不建议使用:避免OOP单继承局限性
实现Runnable接口(本质)(推荐使用)
*实现runnable接口A,重写run方法,执行线程需要将丢入runnable接口
new Thread(testThread3).star();
*推荐使用:灵活,方便同一个对象被多个线程使用
实现Callable接口
1.定义返回值
2.可以抛出异常
创建执行服务,提交执行,获取结果,关闭服务
线程并发问题
同时拿到一张票的问题。
静态代理模式
例如:结婚的婚庆公司
Interface Marry
两个实现:真实角色和代理角色,代理角色在方法重写里面对目标对象(you)进行操作。真实对象和代理角色都会去实现marry接口。一个只管结婚,一个管所有所做的杂事。只需创建一个真实对象作为参数传入代理对象实现的方法。
与多线程的方法:
- Thread类相当于代理对象WeddingCompany
- 代理的是真实对象runnable接口
- happymarry()相当于star
核心代码

*帮助你实现你本身的run方法
Lambda表达式
函数式编程,为了简化
理解函数式接口Functional Interface:
- 任何接口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口
- 对于函数式接口,我们可以通过lambda表达式来创建该接口的对象
public interface Runnable{
public abstract void run();
}
在外面的一个新的对象,实现这个接口,重写它的方法再调用很冗长。
简化过程:实现–>静态内部类–>局部内部类–>匿名内部类


最终:lambda表达式
//lambda
like = () ->{
System.out.println("i like lambda5 ")
};
like.lambda();
线程状态
状态
创建状态–(启动)–>就绪状态<==获得/释放CPU资源==>运行状态(自然执行完毕/外部干涉终止)死亡状态
运行状态(输入休眠等)–>阻塞状态(阻塞解除)–>就绪状态
线程一旦创建就进入到新生状态
调用star之后进入就绪状态
- 设置线程优先级 setPriority(int newPriority)
- 指定毫秒数内让当前执行的线程休眠 static void sleep(long millis)
- 等待该线程终止 void join()
- 暂停当前正在执行的线程对象并执行 其它线程 static void yield()
- 中断线程,别用! void interrupt()
- 测试线程是否处于活动状态,别用! boolean isAlive()
线程停止
推荐使用一个标志位进行终止变量,当flag=false,则终止线程运行。
手写线程停止,改变标志为的状态。
线程休眠
- 每个对象都有一个锁,sleep不会释放锁(线程同步
- sleep可以模拟网络延时:放大问题发生性
- 模拟倒计时 获取当前时间
线程礼让yield
礼让不一定成功
Thread.yield();
JOIN合并线程
先执行此线程,有点像插队。其它线程都阻塞了。
线程状态观测
Thread.State state=thread.getState();
在不同代码位置加上以上代码可以观测线程状态
*线程只能启动一次,线程终端或者结束,一旦进入死亡状态,就不能再次启动
线程优先级
priority 越高越先(!!!不一定(优先级默认是5
有作用但不是每次都,只是大多数
*优先级的设定建议在star()调度前
守护线程daemon
线程分为用户线程和守护线程
- 虚拟机必须确保用户线程执行完毕
- 虚拟机不用等待守护线程执行完毕
- 如,后台记录操作日志,监控内存,垃圾回收等待
线程同步
多个线程操作同一个资源
同一个资源,多人使用:排队
并发问题,修改,线程同步。被修改对象的等待池形成队列,等待前面的线程使用完毕
撤硕:🈶人,有锁
线程同步:队列+锁
*独占问题
同步方法及同步块
private:对象只能被方法访问
synchronized:
- 方法:粒度大,线程阻塞,独占锁问题,影响效率
- 块:synchronized(Obj){}
分析:修改代码才需要同步,只读代码不需要加锁
*难点:锁的对象(变化的量 银行/银行里的钱)
CopyOnWriteList
JUC.concurrent下的
测试JUC安全类型的集合
死锁
都在等待对方释放资源。
产生的必要条件:
- 互斥条件:一个资源每次只能被一个进程使用
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
- 不剥夺:线程已获得的资源,在未使用完之前,不能强行剥夺
- 循环等待:若干进程之间形成一种头尾相连
Lock锁
- 显示锁,需要手动开关
- 只有代码块锁
- 性能更好。JVM调度
可重入锁
线程协助
生产者消费者模式
并发协作模型:管程法(数据缓存区)、信号灯法
管程法
生产者、消费者、产品、缓冲区
//消费者
//产品
//缓冲区
信号灯
给一个flag,标志位解决
线程池
创建线程
发表回复