1.线程的几种状态:
在前面介绍了线程的几种创建方式,现在介绍一下线程的几种状态: 新建、就绪、运行、阻塞、死亡。
新建状态:
线程被创建出来,还没有执行start() 方法开始执行,此时处于新建状态。
就绪状态:
线程并不会自动执行过,当调用线程的start() 方法之后,线程进入就绪状态。处于就续状态的方法并不一定会执行run() 方法,需要和其他的线程竞争CPU时间。
运行状态:
当当前的线程获取到CPU时间,此时开始到运行状态,开始执行run()方法。
阻塞状态:
阻塞状态会有多中情况会导致:
当前线程试图去获取到另外一个线程所持有的锁,会进入阻塞状态。
在线程执行过程当中调用sleep方法,或阻塞一段时间.
在同步方法中调用wait() 会使当前的线程释放锁,进入等待状态,直到获取到notify() 或者 notifyAll() 。
当前线程正在进行一些阻塞的操作,例如IO读操作或者IO写。
死亡状态:
当前线程执行完run() 方法 会正常死亡。
在线程运行过程当中发生异常,会非正常死亡。
2.线程当中几个常用到的属性:
name: 指定当前线程的名字,便于查看
id: 线程的标识
priority: 优先级 1-10 高优先级的线程有较大的概率优先执行。
daemon: 是否为守护线程 守护线程的作用是为其他的线程提供服务。
3. Object类中和线程相关的几个方法:
notify(): 唤醒在此对象监视器上等待的单个线程
notifyAll():唤醒在此对象监视器上等待的所有线程
wait(): 调用此方法会使线程进入等待状态,直到其他线程调用此对象的notify() 或者 notifyAll()
还有两个wait()方法的重载,需要指定时间,一个时间单位为毫秒,另一个时间单位为纳秒。
4.什么是线程的死锁? 如何导致死锁?
死锁: 两个以上的线程需要互相实用对方已经占有的资源,而导致无法运行的现象
通俗点来说就是在当前的线程在占有锁的同时请求获取另外一个锁,而此时正好有一个线程占有另外一个锁而需要请求当前线程占有的锁。
一个死锁的简单实例:
package com.wc.study.thread.demo2;
public class CreateThread {
private static Object o1 = new Object();
private static Object o2 = new Object();
public static void main(String[] args) {
Thread thread1 = new Thread(()->{
synchronized(o1){
System.out.println(Thread.currentThread().getName() + "占有了o1");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized(o2){
System.out.println(Thread.currentThread().getName() + "占有o2");
}
}
});
Thread thread2 = new Thread(()->{
synchronized(o2){
System.out.println(Thread.currentThread().getName() + "占有了o2");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized(o1){
System.out.println(Thread.currentThread().getName() + "占有o1");
}
}
});
thread1.start();
thread2.start();
}
}
运行结果: