线程开启的方式
* 方式一 (继承Thread)
1. 定义类继承Thread
2. 重写run方法
3. 创建Thread的子类对象
4. 调用start方法开启线程
* 线程开启的方式2 (实现Runnable接口)
1. 定义类实现Runnable接口
2. 重写run方法
3. 创建Runnable实现类对象
4. 创建Thread对象,将Runnable实现类对象传入Thread构造
5. Thread对象调用start方法开启线程
* Thread常用功能:
String getName() 获取线程的名称
void setName(String name) 设置线程的名称
static void sleep(long millis) 让执行该代码的线程睡眠指定毫秒值
static Thread currentThread() 获取正在执行此代码的线程
线程安全问题
* 出现的原因:多线程操作共享数据
* 解决线程安全问题的三种方案:
1. 同步代码块:
synchronized(锁对象) {
// 有可能出现线程安全问题的代码
}
2. 同步方法:
把有线程安全问题的代码提取成一个方法,在修饰符上加一个synchronized
非静态同步方法的锁对象默认是:this
静态同步方法的锁对象默认是:当前类.class
3. Lock锁
Lock lock = new ReentrantLock();
在需要同步的代码前调用lock()获取锁
在需要同步的代码后调用unlock()释放锁
线程的状态
* NEW 【新建状态】:线程对象已经创建,但是没有调用start方法
* RUNNABLE 【可运行状态】: 当调用了start方法并且没有陷入睡眠和等待
* BLOCKED 【阻塞状态】:当同步代码中已经有线程在执行,其他的线程处于阻塞状态。
* TIMED_WAITING 【计时等待】:
1. 当调用了Thread.sleep()方法陷入睡眠,没有醒来,此时线程处于等待状态 【不会释放锁对象】
2. void wait(long timeout) 当我们使用锁对象在同步代码块中调用此方法,timeout时间过完之前,也处于计时等待 【会释放锁对象】
* WAITING 【无限等待】:当我们使用锁对象,调用了一个wait()方法,则此线程会无限期等待下去,直到其他的线程叫醒他,才会醒来
* TERMINATED 【终结】 : 当线程调用的run方法执行完毕,则进入死亡(终结)状态
* 等待唤醒:
1. 在同步中
2. 使用锁对象才能调用wait()或者notify() |
|