Java16 多线程知识点
一、进程【理解】1. 定义操作系统(OS)中每一个被执行的应用程序。2. 特点目前操作系统支持多进程并发执行任务。3. 并发原理微观上串行一个一个进程轮流执行获取CPU时间片的进程拥有执行权宏观上并行所有进程看似一起执行。二、线程1. 概念在一个进程中并发执行的多个任务。线程是进程执行任务的单元也被称为轻量级进程。2. 主线程程序默认的单线程以main函数的开始为起点、结束为终点默认执行main函数。3. 线程的组成◦ CPU获取到CPU时间片的线程拥有执行权◦ 数据栈空间独立每个线程有独立的栈空间存储局部变量堆空间共享多个线程可操作同一个堆空间存储对象◦ 程序代码线程执行的逻辑代码4. 代码实现多线程【重点】◦ 方式一继承java.lang.Thread类// 1. 继承Thread类重写run()方法class MyThread extends Thread{Overridepublic void run() {// 线程执行的逻辑}}// 2. 创建线程对象并启动MyThread t1 new MyThread();t1.start(); // JVM自动调用run()方法◦ 方式二实现java.lang.Runnable接口// 1. 实现Runnable接口实现run()方法class MyTarget implements Runnable{Overridepublic void run() {// 线程执行的逻辑}}// 2. 创建目标对象传入Thread对象并启动MyTarget mt new MyTarget();Thread t2 new Thread(mt);t2.start(); // JVM自动调用run()方法三、线程状态【理解】1. 线程状态流转New(初始状态) → 调用start() → Ready(就绪状态) → 获得CPU时间片 → Running(运行状态)Running状态可进入- Terminated(终止状态)run()/main()方法执行完毕- Blocked(阻塞状态)同步代码块获取锁失败- Timed Waiting(限期等待)sleep(time)- Waiting(无限期等待)join()/wait()2. 常用方法◦ static void sleep(long ms)让当前线程进入休眠限期等待释放CPU但不释放锁标记◦ void join()让其他线程优先执行当前线程进入无限期等待如主线程中调用t.join()主线程等待t线程执行完毕再继续四、线程同步【重点】1. 核心概念◦ 临界资源多线程并发时被共享的同一个对象◦ 原子操作不可分割的多步操作执行顺序和步骤不能被打破◦ 线程同步多线程并发访问时保证临界资源的正确性保护原子操作不被破坏2. 同步方式◦ 同步代码块对临界资源对象加锁synchronized(临界资源对象){// 原子操作}原理线程获取锁标记后执行代码执行完毕释放锁获取锁失败则进入阻塞状态。◦ 同步方法用synchronized修饰方法修饰符 synchronized 返回值类型 方法名(形参列表) throws 异常{// 原子操作}等价于对当前对象加锁synchronized(this)。五、线程间的通信1. 核心方法定义在java.lang.Object类中◦ 等待wait()◦ 必须在同步代码块中调用◦ 线程调用后进入无限期等待状态释放锁标记和CPU◦ 通知notify()/notifyAll()◦ notify()通知一个等待的线程结束等待◦ notifyAll()通知所有等待的线程结束等待◦ 注意必须在同步代码块中调用仅起到通知作用不释放锁标记2. 面试题sleep(long ms)和wait()的区别◦ sleep(long ms)线程进入限期等待释放CPU但不释放锁标记◦ wait()线程进入无限期等待释放CPU同时释放锁标记六、线程池【开发应用】1. 概念线程容器预先创建线程存储在池中线程可被重复使用。2. 好处减少创建和销毁线程的次数提高执行效率。3. 常用接口与工具类位于java.util.concurrent包◦ Executor线程池根接口◦ ExecutorService线程池常用子接口◦ submit(Runnable r)提交Runnable任务◦ submit(CallableV c)提交Callable任务◦ shutdown()关闭线程池◦ Executors线程池工具类◦ static ExecutorService newFixedThreadPool(int n)创建固定数量线程池◦ static ExecutorService newCachedThreadPool()创建动态数量线程池七、Callable接口位于java.util.concurrent包【开发应用】1. 概念JDK5.0新增与Runnable类似代表线程任务支持返回值和抛出异常。2. 核心方法V call()带有泛型返回值可抛出任意类型异常。3. 调用方式◦ 同步调用调用者需等待被调用方法执行完毕再继续◦ 异步调用调用者无需等待可直接执行后续逻辑4. Future接口接收异步计算结果通过get()方法获取Callable任务的返回值。八、常用集合补充1. 队列Queue先进先出FIFO结构是Collection的子接口。◦ 常用方法add()/offer()添加元素、poll()获取并移除队头元素◦ 实现类LinkedList、BlockingQueue阻塞队列如ArrayBlockingQueue、LinkedBlockingQueue2. 线程安全集合工具方法Collections.synchronizedXXX()系列方法将非线程安全集合转换为线程安全集合3. 锁的应用◦ Lock接口比synchronized更灵活ReentrantLock是实现类lock()获取锁、unlock()释放锁建议在finally中释放◦ ReadWriteLock读写锁支持读多写少场景读读不互斥、读写/写读/写写互斥提高读操作效率4. 线程安全且高效的集合类◦ CopyOnWriteArrayList写操作加锁并复制新数组读写不互斥读多写少场景效率高◦ ConcurrentLinkedQueue基于CAS算法实现的线程安全队列◦ ConcurrentHashMap分段锁JDK7/CASSynchronizedJDK8实现锁粒度小并发效率高不允许null键值5. 多线程实现方式总结1. 继承Thread类重写run()方法调用start()启动2. 实现Runnable接口实现run()方法传入Thread对象启动3. 实现Callable接口实现call()方法借助线程池提交任务补充集合体系回顾多线程相关Collection├─ List有序、有下标、元素可重复│ ├─ ArrayList线程不安全│ ├─ Vector线程安全│ └─ CopyOnWriteArrayList线程安全读多写少├─ Set无序、无下标、元素不可重复│ ├─ HashSet│ ├─ SortedSet → TreeSet│ └─ LinkedHashSet└─ Queue先进先出├─ ConcurrentLinkedQueue├─ LinkedList└─ BlockingQueue → ArrayBlockingQueue/LinkedBlockingQueueMap├─ HashMap线程不安全├─ Hashtable线程安全├─ LinkedHashMap├─ ConcurrentHashMap线程安全└─ SortedMap → TreeMap