多个任务同时执行,主线程和子线程并行交替进行。
一个进程可以有多个线程。
进程是执行程序的一次过程,是一个动态的概念。
线程是CPU调度和执行的单位,线程的先后执行顺序不可以人为干预。
main — 主线程 gc — 垃圾回收线程
线程创建Thread classRunnable 接口Callable 接口 Thread 类
步骤:
自定义线程类继承 Thread 类重写 run() 方法,编写线程的线程函数体创建线程对象
线程创建不一定立即执行,由CPU调度。
Runnable 接口步骤:
实现 runnable 接口重写 run() 方法执行线程对象
由于 Java 不支持多继承,故推荐实现 Runnable 接口。
Callable 接口步骤:
实现 Callable 接口,需要设置返回值类型重写 call() 方法,需抛异常创建对象,创建执行服务提交执行,获取结果关闭服务
静态代理模式:
真实对象和代理对象必须实现同一个接口,代理对象代理真实对象 Lambda 表达式 认识
避免匿名内部类定义过多实质属于函数式编程接口只能有一个抽象类方法多个参数也可省略参数类型 线程状态
五大状态:
创建状态 ---- 就绪状态 ---- 阻塞状态 ---- 运行状态 ---- 死亡状态
停止线程
JDK 推荐的 stop()、destroy() 方法已被弃用,不建议使用
建议设置标志位,通过标志位线程自己停止
线程休眠sleep() 中的参数指定当前线程阻塞的毫秒数sleep() 方法中可能存在异常sleep() 后的线程在设定的时间后,会进入就绪状态每个对象都有一个锁,sleep() 方法不会释放锁 线程礼让(yield)
让当前正在执行的线程暂停,不是阻塞!
将线程从运行状态转为就绪状态
让 CPU 重新调度,礼让不一定成功!
线程合并Join 合并线程,等待该线程执行完毕后,才可以执行其他线程,其他线程只能处于阻塞状态 线程的优先级
Java 会提供一个线程调度器来监控程序中的所有处于就绪状态的线程,按照优先级来调度线程
优先级用数字表示,优先级范围:1-10
优先级的高低不决定调度的顺序,只是决定获得 CPU 调度的概率!
守护线程线程分为用户线程和守护线程虚拟机必须确保用户线程执行完毕虚拟机不用等待守护线程执行失败虚拟机关闭需要一小段时间 线程同步
同步:多个线程操作同一个资源
线程同步会使得性能降低,但安全性提高!
并发
同一个对象被多个线程同时操作
队列和锁
队列+锁 才能保证线程同步的安全性!
锁机制 synchronized
同步方法
synchronized 关键字
synchronized 方法synchronized 块锁使用太多,会浪费资源,影响效率
同步块
synchronized(obj){}
Obj 称为 同步监视器
Obj 可以是任何对象 对于普通同步方法,锁是当前实例对象。 如果有多个实例,那么锁对象必然不同,无法实现同步。对于静态同步方法,锁是当前类的Class对象,可以有多个实例,但是锁对象是相同的 ,可以完成同步。对于同步方法块,锁是Synchonized括号里配置的对象。对象最好是只有一个的,如当前类的 class是只有一个的。锁对象相同,也能实现同步。
死锁
两个或两个以上的线程都在等待其他线程释放资源,导致停止执行
某一个同步块同时拥有两个以上对象的锁
产生死锁的条件:
互斥:一个资源只能被一个线程使用请求与保持:一个线程因请求资源而阻塞时,对已获得的资源保持不变不剥夺:线程已获得的资源,在未使用完之前,不能强行剥夺循环等待:若干线程之间形成一种头尾相接的循环等待资源关系
锁(Lock)
JDK5.0 开始,提供过了更加强大的线程同步机制----显式定义同步锁每次只能有一个线程对Lock对象加锁,线程开始访问共享资源前需线获得Lock对象
区别
Lock是显式锁,synchronized 是隐式锁
使用Lock锁,JVM虚拟机花费在调度线程的时间更少,性能更好
线程协作生产者消费者模式 —> 问题
synchronized 只能阻止并发更新同一个共享资源,实现了线程的同步synchronized 不能实现不同线程之间的通信
解决生产者消费者问题,有:
管程法信号灯法 线程池
经常创建和销毁、使用量特别大的资源,如并发情况下,对性能运行影响极大
好处
提高响应速度降低资源消耗便于线程管理
使用
ExecutorService:真正的线程池接口
Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池



