天天看点

多线程

多线程

多线程

程序:程序是指令和数据的有序集合,是一个静态的概念

进程:执行程序的一次执行过程,是一个动态的概念,进程是资源分配的单位

线程:一个进程中有若干个线程,线程是cpu调度和执行的单位

如:视频中同时可以听声音、看图像、看弹幕

数据紊乱

结果

使代码变得更简洁

去掉一些没有用的代码,只留下核心代码

避免内部类定义过多

函数式接口:一个接口只有一个方法

函数式接口可以使用lambda表达式

五个状态

创建状态: new thread()线程对象一旦创建就进入到新生状态

就绪状态:start() 调用方法后进入,但不意味着立即执行 ,等待cpu的调度执行

阻塞状态:调用sleep,wait或同步锁定

运行状态:进入运行状态,线程才真正执行线程体的代码块

死亡状态:线程中断或者结束,一旦进入死亡,就不能再次启动

模拟网络延时:放大问题的发生性

模拟倒计时

让cpu重新调度,不一定成功,看cpu

合并线程,待此线程完成后,在执行其他线程,其他线程阻塞

少使用,会阻塞

优先级越高,cpu调用的机会越大

daemon

线程分为用户线程和守护线程

虚拟机必须等用户线程执行完毕

虚拟机不用等守护线程执行完毕,只关注用户线程结束后,结束程序

**并发 **

同一个对象被多个线程同时操作

队列和锁

形成线程同步的条件:队列+锁。

每个对象对应一把锁

线程同步是为了安全

同步方法

synchronized方法和synchronized块

控制对象的访问,每个对象一把锁,方法一旦执行,就独占该锁,知道方法返回释放锁

缺陷:会影响效率

锁的对象为变化的量,增删改

某一个同步块同时拥有“两个以上对象的锁”,可能产生死锁的问题。

产生死锁的四个必要条件

互斥条件:一个资源只能被一个进程使用

请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放

不剥夺条件:进程已获得资源,在未使用完前,不能强行剥夺

循环等待条件:若干进程之间形成一种头尾相接的循环等待资源的关系

显式定义同步锁(手动开启和关闭,别忘记关锁),只有代码块锁

synchronized是隐式锁,出了作用域后自动释放,有代码块和方法锁

reentrantlock类实现了lock

生产者消费者模式

生产者和消费者共享同一个资源,并且生产者和消费者之间相互依赖,互为条件

生产者:没有生产产品之前,需要通知消费者等待,生产产品后,需要通知消费者消费

消费者:消费后,通知生产者生产新的产品以供消费

synchronized可阻止并发更新同一个共享资源,实现了同步,但不能实现不同线程之间的消息传递

wait()

线程一直等待,直到其他线程通知,会释放锁

wait(long timeout)

notify()

唤醒一个处于等待的线程

notifyall()

唤醒同一个对象所有wait的线程,优先级高的线程优先调度

使用线程池,对性能好

提高响应速度

降低资源消耗

便于线程管理

executorservice和executors: