线程的状态
1、new新建状态:线程刚被创建,但是没有启动,还没有调用start方法
2、Runable可运行状态:线程可以在JVM中运行,即抢夺到CPU的使用权
3、Blocked锁阻塞状态:当一个线程试图获取一个对象锁时,但是该对象被其他线程持有,该线程就会进入Blocked状态进行等待,当获得锁时,进入Runable状态
4、Waiting无限等待状态:一个线程在等待另一个线程执行一个(唤醒动作)时,该线程进入Waiting状态,进入这个状态是无法自动唤醒的,必须等待另一个线程调用notify或者notifyAll方法才能唤醒
5、Timed Waiting 计时等待状态:同Waiting状态,有几个方法有超时参数,调用他们进入Timed Waiting 计时等待状态,这一状态将一直保持到超时期满或者收到唤醒通知,带有超时参数的常用方法有:Thread.sleep、Object.wait
6、Terminated死亡状态:当线程执行完run方法,或者执行了stop方法(过时方法),或者run方法中出现异常,就会进入到死亡状态
等待唤醒案例—>线程之间的通信
waiting无限等待状态代码
public class demo_main {
public static void main(String[] args) {
//创建一个object对象,利用其wait和notify方法进行唤醒
Object obj=new Object();
//创建一个顾客买包子的线程,让其说明自己想要的包子类型,然后进入waiting无限等待状态,等待老板唤醒
new Thread(){
@Override
public void run() {
synchronized (obj) {
System.out.println("告知老板包子的种类和数量然后进入等待");
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
//老板做完包子之后吃包子
System.out.println("包子真好吃,再来一份");
}
}
}.start();
//创建老板线程,顾客说完之后进行做包子,做完只有唤醒顾客,给顾客包子
new Thread(){
@Override
public void run() {
//花了5秒做包子
System.out.println("我正在做包子,别着急");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj){
System.out.println("给你包子");
obj.notify();
}
}
}.start();
}
}
Object类中wait带参数方法和notify方法
进入TimeWaiting计时等待状态的两种方式
1、使用sleep(long m)方法,在毫秒值结束之后,线程睡醒进入到Runnable/Blocked状态
2、使用wait(long m)方法,wait 方法如果在毫秒值结束之后,还没有被notify唤醒,就会自动醒来,线程睡醒进入到Runable /Blocked状态
唤醒的方法:
1、void notify() 唤醒在此对象监视器上等待的单个线程
如果调用notify方法时,有多个正在处于无限等待状态或者计时等待状态的线程,会唤醒其中随机的一个线程
2、void notifyAll() 唤醒在此对象监视器上等待的所有线程
线程之间的通信
概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不同。
必要性: 多个线程并发执行时,在默认情况下CPU是随机切换线程的,当我们需要多个线程来共同完成一个任务,并且我们希望他们有规律进行时,那么多个线程之间就需要一些协调通信,以此来达到多个线程共同操作一份数据的目的。
如何保证线程之间有效利用资源:利用 “等待唤醒机制”