- 多线程
- 多线程的好处是什么?
- 发挥多核CPU的效率
- 有什么需要注意的?
- 线程不能独立存在,需要依附于进程
- 什么是进程?
- 一个应用程序就是一个或多个进程
- 什么是线程?
- 线程的运行方式
- 并行(必须是多核CPU)
- 一个或多个事情(任务)在同一时间点(同时)执行
- 并发(一个核也行)
- 一个或多个事情在同一时间段(有先后顺序)执行
- 并行(必须是多核CPU)
- 调度方式
- 分时调度
- 给每个任务分配的时间相同
- 抢占式调度
- 给每个任务分配的时间不等
- 分时调度
- 一个Thread类就是一个线程
- Thread类
- 所属包:java.lang
- 构造方法:
- 无参:public Thread();
- public Thread(String name);创建线程并起名
- public Thread(Runnable target);创建Runnable接口类型的线程
- Runnable接口:
- 抽象方法:public abstract void run();
- Runnable接口:
- public Thread(Runnable targt,String name);创建Runnable接口类型的线程并起名
- 静态方法:
- Thread.currentThread();获得当前线程
- Thread.sleep(long millis);让线程进入即使等待状态
- 成员变量:
- private Runnable target;
- 成员方法:
- void start();启动线程并执行run方法中代码
- void run();需要子线程执行的代码写在里面
- String getName();获取当前线程的名称
- void setName(String naem);给当前线程改名
- 注意事项
- Runnable接口的方式和继承Thread类的方式,建议使用Runnable类型方式
- a.线程和任务分类,解耦合,提高代码的健壮性
- b.避免了Java单继承的局限性
- c.线程池里面只能传入Runnable类型和Callable类型的对象,不用new Thread。
- 每一个线程启动后都会有一个栈,各自在各自的栈中执行任务
- 线程的开销比一般对象的开销要大
- Runnable接口的方式和继承Thread类的方式,建议使用Runnable类型方式
- Thread类
- 线程安全
- 前提:多个线程访问统一资源(数据)
- 整个操作不是原子操作,可能会引起多个线程同时取值赋值,造成数据错误
- 解决方法
- 1.使用synchronized代码块
- 语法:synchronized(锁对象)锁对象可以是任意引用数据类型的对象{写有可能发生线程安全问题的代码}
- 2.使用synchroniezd方法
- 静态synchronized方法
- 在static和返回值之间加synchronized关键字
- 锁对象是当前类的反射对象
- 获取当前类的反射对象Class 变量名=类名.class
- 锁对象是当前类的反射对象
- 在static和返回值之间加synchronized关键字
- 非静态synchronized方法
- 返回值之间加synchronized关键字
- 锁对象是this
- 返回值之间加synchronized关键字
- 静态synchronized方法
- 3.lock锁
- lock接口
- 上锁:void lock();
- 开锁:void unlock();
- 常用实现类
- ReentrantLock
- 构造方法:public ReenstrantLock();
- ReentrantLock
- lock接口
- 只要事项:
- 想要达到线程安全的效果,必须是同一个锁对象
- synchronized代码块和synchronized方法执行代码完毕后,会自动释放锁对象
- lock锁需要手动释放
- synchronized代码块和synchronized方法在发生异常后,会自动释放锁对象
- lock锁对象在发生异常后,不会手动释放锁对象,所以建议把手动释放锁对象的代码卸载finally块中
- try{可能发生异常的代码}finally{lock.unlock();}
- 1.使用synchronized代码块
- 前提:多个线程访问统一资源(数据)
- 线程的状态
- Java中现场的状态
- NEW
- 新建状态:现场刚创建完毕,启动之前就处于这种状态
- RUNNABLE
- 可运行状态:线程正在执行run方法中的代码就处于这个状态
- BLOCKED
- 阻塞状态:获取synchronized锁对象失败就出院这种状态
- WAITING
- 无限等待状态:获取lock锁对象失败,或执行Obj.wait()或Obj.wait(0)方法就处于该状态
- TIMED_WAITING
- 计时等待状态:线程指向Thread.Sleep(long millis)或Obj.wait(long time)方法就处于该状态。
- TERMINATED
- 消亡状态:现场执行完任务后,就处于该状态
- NEW
- Thread类成员方法
- State getState();获取线程状态
- Java中现场的状态
- 线程的通信:线程和线程之间的沟通
- 等待唤醒机制
- Object类方法
- void wait();执行此方法会让线程进入等待状态(WAITING)。
- void wait(long time);调用该方法会让线程进入计时等待状态(TIMED_WAITING).
- void notify();调用该方法会让线程醒来接着执行任务
- void notifyAll();待遇该方法,会唤醒当前锁对象上等待的所有线程
- 主要事项:
- 1.这些方法都必须写在synchronized代码块或synchronized方法中
- 2.调用这些方法的对象,必须和锁对象一致
- 3.当前锁对象.notify();只能唤醒当前锁对象上等待的线程
- 调用wait(不管有没有参数)方法,会自动释放锁对象
- Object类方法
- 等待唤醒机制
- 线程池
- 优点
- 1.提高响应速度:线程池预先创建好了线程,只能任务来执行。
- 2.降低资源消耗:线程池中的线程执行完任务后,不会进入TERMINATED状态,而是会返回线程池继续等待。
- 3.提高线程的可管理性:一个线程大约需要消耗1M的空间,线程池可以设置线程的最大数量。避免内存溢出。OutOfMenmoryError
- 创建:Executors类
- Static ExecutorService NewFixedTreadPool(int nThread);创建一个固定线程池 参数为线程的最大数量
- ExecutorService接口
- void execute(Runnable r);执行任务
- <T> Futrue<T> submit(Collable c);执行Callable类型线程执行任务,并返回结果
- Future<T>接口
- T get();获得Callable的抽象方法的返回值
- Callable<T>接口
- public abstract T Call():
- Future<T>接口
- Future<T> submit(Runnable r);执行Runnable类型的线程 并返回null
- void Shutdown();关闭线程池
- 注意事项
- 必须等子线程把任务执行完,return以后,才可以获取返回的结果。
- 优点
- 线程的运行方式
- 什么是进程?
- 线程不能独立存在,需要依附于进程
- 注意事项
- 多线程执行的时候,谁先执行不确定,谁执行多久也不确定
- 多线程的好处是什么?
java多线程简述
于 2022-06-06 11:01:07 首次发布