佛山网站建设开发团队,房产发布网站建设,好用的外贸网站,专业的网站开发建访目录
1.基本概念
2.创建线程方式
2.1直接建立线程
2.2实现Runnable接口
3.3实现Callable接口
3.4 了解Future接口
Future模式主要角色及其作用
3.5实例化FutureTask类
3.实现线程安全
3.1定义
3.2不安全原因
3.3解决方案
3.4volatile与synchronized区别
4.极端情…目录
1.基本概念
2.创建线程方式
2.1直接建立线程
2.2实现Runnable接口
3.3实现Callable接口
3.4 了解Future接口
Future模式主要角色及其作用
3.5实例化FutureTask类
3.实现线程安全
3.1定义
3.2不安全原因
3.3解决方案
3.4volatile与synchronized区别
4.极端情况——线程死锁
4.1定义
4.2解决措施
5.多线程通信
6.线程池的掌握
6.1核心参数
6.2常见线程池
6.3自定义线程池
6.4操作步骤 1.基本概念 线程状态新建New、就绪Runnable、运行Running、阻塞Blocked、 等待Waiting、超时等待Timed Waiting、终止Terminated 锁同步监视器分为悲观锁和乐观锁常见的有偏向锁、轻量级锁、重量级锁 CASCompare And Swap是一种乐观锁的实现方式通过比较并 交换来实现并发控制 2.创建线程方式 Runnable接口、Callable接口、Future接口、FutureTask类 2.1直接建立线程 创建Thread子类按需求重写run方法 【run代表此线程执行时会做的事】 这里的属性若为 多线程共享属性加static修饰 2.2实现Runnable接口 这里的 多线程共享属性 可以是非静态的因为多线程共用此接口 3.3实现Callable接口
1实现接口Callable重写call()回调方法会返回一个值值类型由Callable泛型决定 实例化上述类利用FutureTask(Callable)构造器实例化类 3.4 了解Future接口 异步调用的多线程开发模式之一异步当我们需要调用一个函数方法时并不急着要结果。让被调者立即返回让它在后台慢慢处理这个请求此时则可以先处理一些其他任务 Future模式主要角色及其作用 Main-调用Client发送请求 Data-返回数据的接口 Client-返回Data对象立即返回FutureData,并开启ClientThread线程装配RealData FutureData-虚拟数据伪造数据立即返回最终装配上RealData RealData-真实数据构造缓慢 3.5实例化FutureTask类 FutureTask用于异步获取执行结果或取消执行任务 通过传入Runnable或者Callable的任务给FutureTask 直接调用其run方法或者放入线程池执行 最后在外部通过FutureTask的get方法异步获取执行结果适合耗时操作 3.实现线程安全
3.1定义 多线程环境下对共享资源的访问不会导致数据出错。 因此和单线程执行相同的操作结果相同 3.2不安全原因 1. 线程是抢占式的执行线程间的调度充满了随机性 2. 多个线程对同一个变量进行修改操作 3. 对变量的操作不是原子性的 4. 内存可见性导致的线程安全问题 5. 指令重排序也会影响线程安全 3.3解决方案
使用同步机制如synchronized、Lock、
使用线程安全的数据结构如ConcurrentHashMap synchronized:Java关键字属于隐式锁可以修饰方法或代码块 LockJAVA接口显式锁 原理上都是通过对共享资源加锁来实现同步。 3.4volatile与synchronized区别 volatile关键字用于保证变量的可见性 而synchronized既保证可见性又保证原子性 volatile适用于单个变量的读写操作而synchronized适用于复合操作或临界区。 4.极端情况——线程死锁
4.1定义 多个线程相互等待对方释放资源导致无法继续执行 4.2解决措施 避免嵌套锁、 按固定的顺序获取锁、 设置超时时间、 使用Lock对象代替synchronized关键字。 5.多线程通信
通过共享变量、wait()和notify()、BlockingQueue等机制来实现线程间的数据交换和协作
6.线程池的掌握
6.1核心参数 核心线程数(corePoolSize)依据任务的处理时间和每秒产生的任务数量来确定 最大线程数(maximumPoolSize)参照核心线程数和系统每秒产生的最大任务数决定 线程空闲时间(keepAliveTime)用户自设置合理时间间隔 任务队列长度(workQueue)大于等于任务队列长度就丢弃多的任务 6.2常见线程池
FixedThreadPool、CachedThreadPool、ScheduledThreadPool
6.3自定义线程池 1:编写任务类(MyTask),实现Runnable接口; 2:编写线程类(MyWorker),用于执行任务,需要持有所有任务; 3:编写线程池类(MyThreadPool),包含提交任务,执行任务的能力; 4:编写测试类(MyTest),创建线程池对象,提交多个任务测试; 如下模板
package com.itheima.demo01;import java.util.Collections;
import java.util.LinkedList;
import java.util.List;/*这是自定义的线程池类;成员变量:1:任务队列 集合 需要控制线程安全问题2:当前线程数量3:核心线程数量4:最大线程数量5:任务队列的长度成员方法1:提交任务;将任务添加到集合中,需要判断是否超出了任务总长度2:执行任务;判断当前线程的数量,决定创建核心线程还是非核心线程*/
public class MyThreadPool {// 1:任务队列 集合 需要控制线程安全问题private ListRunnable tasks Collections.synchronizedList(new LinkedList());//2:当前线程数量private int num;//3:核心线程数量private int corePoolSize;//4:最大线程数量private int maxSize;//5:任务队列的长度private int workSize;public MyThreadPool(int corePoolSize, int maxSize, int workSize) {this.corePoolSize corePoolSize;this.maxSize maxSize;this.workSize workSize;}//1:提交任务;public void submit(Runnable r){//判断当前集合中任务的数量,是否超出了最大任务数量if(tasks.size()workSize){System.out.println(任务:r被丢弃了...);}else {tasks.add(r);//执行任务execTask(r);}}//2:执行任务;private void execTask(Runnable r) {//判断当前线程池中的线程总数量,是否超出了核心数,if(num corePoolSize){new MyWorker(核心线程:num,tasks).start();num;}else if(num maxSize){new MyWorker(非核心线程:num,tasks).start();num;}else {System.out.println(任务:r 被缓存了...);}}}
6.4操作步骤 1:利用Executors工厂类的静态方法,创建线程池对象; 2:编写Runnable或Callable实现类的实例对象; 3:利用ExecutorService的submit方法或ScheduledExecutorService的schedule方 法提交并执行线程任务 4:如果有执行结果,则处理异步执行结果(Future) 5:调用shutdown()方法,关闭线程池