多线程
来源:互联网 发布:h3c网络工程师证书知乎 编辑:程序博客网 时间:2024/06/12 00:12
一、线程的状态
二、创建线程的方式
1、继承Thread类
2、实现 Runnable接口
2.1、定义类实现Runnable接口
2.2、覆盖接口中的run方法,将线程的任务代码封装到run方法中
2.3、通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递
为什么? 因为线程的任务都封装在Runnable接口子类对象的run方法中,所以要在线程对象创建时就必须明确要运行的任务
2.4、调用线程对象的start方法开启线程
三、实现Runnable接口的好处
3.1、将线程的任务从线程的子类中分离出来,进行了单独的封装。按照面向对象的思想将任务封装成对象
3.2、避免了java单独继承的局限性
创建线程较常用的方式为 implements Runnable 接口
四、线程安全问题
4.1、线程安全问题产生的原因:
多个线程在操作共享的数据
操作共享数据的线程代码的多条
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。
4.2、同步代码块
同步代码块中的对象代表什么?
4.3、同步函数与同步代码块的区别
同步函数的锁是固定的this
同步代码块的锁是任意的对象
(建议使用同步代码块)
4.4、静态同步函数的锁
该函数所属字节码文件对象 可以用this.class
4.5、单例模式涉及的多线程问题
五、线程间通信
多个线程在处理同一资源,但是任务却不同
5.1、等待唤醒机制
涉及的方法:
1、wait():让线程处于冻结状态,被wait的线程会被存储到线程池中
2、notify():唤醒线程池中一个线程(任意)
3、notifyAll():唤醒线程池中的所有线程
这些方法都必须定义在同步中,因为这些方法是用于操作线程状态的方法,必须要明确到底操作的是哪个锁上的线程
为什么操作线程的方法wait、notify、notifyAll定义在了Object类中? 因为这些方法是监视器的方法,监视器其实就是锁,锁可以是任意对象,任意的对象调用的方式一定定义在Object类中。
5.2、多生产者多消费者问题
if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。
while判断标记,解决了线程获取执行权后,是否要运行
notify只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+ notify会导致死锁
notifyAll解决了本方线程一定会唤醒对方线程的问题
5.3、JDK1.5新特性 Lock
将同步和锁封装成了对象,并将操作锁的隐式方式定义到了该对象中,将隐式动作变成了显示动作。
5.4、JDK1.5新特性Condition
六、wait与sleep的区别
6.1、wait可以指定时间也可以不指定
sleep必须指定时间
6.2、在同步中时,对CPU的执行权和锁的处理不同
wait:释放执行权,释放锁
sleep:释放执行权,不释放锁
七、停止线程方式
1、stop方法
2、run方法结束
怎么控制线程的任务结束?任务中都会有循环结构,只要控制住循环就可以结束任务。控制循环通常就用定义标记来完成。
7.1、定义标记
7.2、Interrupt
但是如果线程处于了冻结状态,无法读取标记。如何?
八、守护线程(setDaemon)
九、其他方法
9.1、join
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- springmvc之定时器
- Ugly Number II
- 归并排序 -- 高效、稳定的排序算法
- poj1023 进制
- BZOJ3926-[Zjoi20150]诸神眷顾的幻想乡
- 多线程
- JDK1.8源码中的编程习惯
- ZOJ 3610 Yet Another Story of Rock-paper-scissors
- axis2开发webservice之编写Axis2模块(Module)
- Sam 数(矩阵乘法)
- curl 中post 传参数给server
- Maperitive Mapnik style rule
- Codeforces Round #352 (Div. 2)-B. Different is Good(模拟)
- Java之properties文件读取