一、线程和进程的概念
1.进程:正在运行的一个应用程序:多个进程共享cpu
2.线程:组成进程的最小的单元,单一运行的顺序流:多个线程共享进程分配的cpu
二、创建的线程的两种
1.extends Thread类: 当前就是线程类
2.implements Runnable接口:当前类是线程类的target
注意:两种方式的区别
三、线程的生命周期:五个阶段:
新建阶段、就绪阶段、运行阶段、阻塞阶段、死亡阶段
每个阶段的特点:互相转换的条件
四、线程中常见的方法:
1.start():启动线程的方法
2.stop():摒弃的方法,可能导致数据不安全
3.suspend():摒弃的方法,可能导致死锁
4.resume():摒弃的方法.
5.join():阻塞主线程,插队的子线程执行完毕后,主线程才能执行
6.yield():让位:只给优先级高的线程让位,将运行的线程进入就绪状态
7.sleep(millsecond):可以用在任何地方
8.wait():等待
sleep()和wait()区别:
- 拥有对象不同:wait是任何对象的方法,sleep是Thread的方法
- wait可以释放对象锁,sleep保留对象锁
- wait可以是任意对象来调用,sleep只能线程调用
- wait可以通过notify随时唤醒,sleep只能等待设定时间结束后自然唤醒,否则将引发异常
- wait必须在同步方法或同步块中进行调用,sleep可以在任意位置调用
五、线程同步问题:
1.什么是线程安全问题?多条线程同时访问一个资源,所产生的数据不一致的问题
2.如何保证线程安全?
第一种方式:
使用同步锁:synchronized:
synchronized :修饰代码段 :
语法:
synchronized(对象-同步监视器){
被锁的代码段
}
同步监视器只能是引用类型的。多条线程锁的是同一个对象
修饰方法:语法 public synchronized void method(){}
同步的方法,对该方法进行锁定,并且调用当前方法的对象
第二种方式:
使用Lock锁:ReentrantLock类
区别:
1.synchronized 关键字,jdk提供的。ReentrantLock类
2.synchronized 可以修饰代码段,也可以修饰方法。但是ReentrantLock只能用于代码段
3.如果资源竞争不太激烈时,效率没太大差别,如果资源竞争非常激烈时,ReentrantLock比synchronized 高很多。
4.synchronized 运行完代码段自动解锁,但是lock锁必须手动调用unlock()方法,有可能造成死锁:才要把unlock()写在finally中
5.synchronized阻塞其他线程的,但是lock可以使用tryLock()尝试获取锁,不一定非要阻塞。
第三种方式:ThreadLocal:以空间换取时间
六、wait和notify进行协作或者通信
1.wait只能有notify唤醒,并且调用wait和notify的对象必须是同一个。