线程状态
线程状态:五种状态
1.新生状态:new
2.就绪状态:调用start方法,线程就会进入就绪队列
3.执行状态:当CPU调度就绪的线程,线程开始执行
4.阻塞状态:线程一旦进入阻塞状态,需要等待阻塞解除
5.终止状态:线程执行完毕
**注意:**当线程进入阻塞状态,阻塞解除后不会直接恢复到执行状态,而是进入就绪状态,等待CPU的下一次调度
线程进入终止状态,无法恢复
**如何进入终止状态:**1.正常执行完毕
2.stop()方法,已过时,不推荐
3.添加标识判断—>推荐
**如何进入就绪状态:**1.start()
2.阻塞解除
3.线程切换,CPU调度
4.yield()礼让
**如何进入阻塞状态:**1.sleep()
2.join()
3.wait()
4.IO
sleep:线程休眠
作用:1.模拟网络延迟
2.放大问题出现的可能性
特点:一个线程进入休眠状态,会自动让出CPU资源,CPU可能会调度其他资源
抱着资源睡觉—>资源值得是对象的锁资源
//模拟倒计时
public class Class004_Test implements Runnable{
public static void main(String[] args) {
for(int i=10;i>=0;i--){
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
}
}
yield,礼让线程
让出CPU资源,直接进入到就绪状态
public class Class002_Yield implements Runnable{
public static void main(String[] args) {
Class002_Yield cy = new Class002_Yield();
new Thread(cy,"A").start();
new Thread(cy,"B").start();
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"开始了....");
Thread.yield();
System.out.println(Thread.currentThread().getName()+"结束了....");
}
}
join,插队线程
void join() 等待这个线程死亡。
void join(long millis) 此线程最多等待 millis毫秒。
void join(long millis, int nanos) 此线程最多等待 millis毫秒加上 nanos纳秒。
被插队的线程会进入到阻塞状态
注意:先就绪后插队
class Father implements Runnable {
public static void main(String[] args) {
Thread td=new Thread(new Father());
td.start();
}
public void run() {
System.out.println("-----执行父亲线程-----");
System.out.println("想吸烟,让儿子去买烟");
//创建儿子线程
Thread th=new Thread(new Son());
th.start();
try {
th.join();
}catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("拿到烟,猛吸一口");
System.out.println("-----父亲线程结束-----");
}
}
class Son implements Runnable{
public void run() {
System.out.println("-----执行儿子线程-----");
System.out.println("接过钱,去买烟");
System.out.println("路上看见一家游戏厅,进去玩一会儿");
for(int i=1;i<=10;i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i+"秒过去了");
}
System.out.println("赶紧去买烟");
System.out.println("把烟上交");
System.out.println("-----儿子线程结束-----");
}
}
中断线程
void interrupt() 为该线程添加中断标识
boolean isInterrupted() 判断该线程是否曾经调用interrupt()方法添加过中断标识
static boolean interrupted() 判断该线程是否曾经调用interrupt()方法添加过中断标识,同时会复位这个标识
当线程处于休眠过程(执行sleep()方法),如果线程被添加了中断标识,会遇到此异常InterruptedException - 如果有任何线程中断了当前线程。 抛出此异常时,将清除当前线程的中断状态 。
public class Class004_Interrupt implements Runnable{
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i = 1;i<=10;i++){
if(Thread.interrupted()){ //复位
System.out.println("添加了中断标识,即将结束线程");
System.out.println(Thread.currentThread().isInterrupted()); //只判断
break;
}
System.out.println("---------------------"+i+"---------------------");
}
}
public static void main(String[] args) {
Thread th = new Thread(new Class004_Interrupt());
th.start();
System.out.println(th.isInterrupted()); //false
//添加中断标识
th.interrupt();
System.out.println(th.isInterrupted()); //true
}
}
线程的分类
**线程的分类:**1.用户线程:创建新的线程默认为用户线程
2.守护线程:守护用户线程的执行
守护线程:SetDaemon(true)
如果存在多个用户线程,需要所有的用户线程全部执行完,JVM才会正常退出
当所有用户线程全部执行完毕,守护线程直接结束退出
垃圾回收机制是一个典型的守护线程的案例
public class Class005_Daemon implements Runnable{
public static void main(String[] args) {
Thread th = new Thread(new Class005_Daemon());
//为th线程设置为守护线程
th.setDaemon(true);
//开启线程
th.start();
//主线程具体代码
for(int i = 1;i<=20;i++){
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("正在吃第"+i+"根面条...");
}
}
@Override
public void run() {
int i = 1;
while(true){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("守护线程----->"+i++);
}
}
}
获取线程状态getState()
Thread.State:线程状态。线程可以处在以下状态之一
NEW -> 新生
尚未启动的线程处于此状态。
RUNNABLE -> 就绪|运行
在Java虚拟机中执行的线程处于此状态。
BLOCKED -> 等待获取对象锁资源的过程
被阻塞等待监视器锁定的线程处于此状态。
WAITING -> wait(),join()等
无限期等待另一个线程执行特定操作的线程处于此状态。
TIMED_WAITING -> 与时间相关的等待 sleep(ms) ,wait(ms),join(ms)等
正在等待另一个线程执行最多指定等待时间的操作的线程处于此状态。
TERMINATED -> 终止
已退出的线程处于此状态。
public class Class006_getState implements Runnable{
public static void main(String[] args){
Thread th = new Thread(new Class006_getState());
System.out.println(th.getState()); //NEW
th.start();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
while(true){
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(th.getState());
//如果th线程是终止状态,循环结束
if(th.getState()==Thread.State.TERMINATED){
break;
}
}
}
@Override
public void run() {
for(int i=1;i<=10;i++){
if(i==5){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i);
}
}
}
线程优先级getPriority
线程优先级getPriority:优先执行哪一个线程的概率高
1~10:1,最小
10,最大
5,默认
void setPriority(int newPriority) 更改此线程的优先级。
int getPriority() 返回此线程的优先级。
static int MAX_PRIORITY 线程可以拥有的最大优先级。
static int MIN_PRIORITY 线程可以拥有的最低优先级。
static int NORM_PRIORITY 分配给线程的默认优先级。
public class Class007_Priority implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
Class007_Priority cp = new Class007_Priority();
Thread th1 = new Thread(cp,"A");
Thread th2 = new Thread(cp,"B");
Thread th3 = new Thread(cp,"C");
th1.setPriority(1);
//th3.setPriority(10);
th3.setPriority(Thread.MAX_PRIORITY);
System.out.println(th1.getPriority());
System.out.println(th2.getPriority());
System.out.println(th3.getPriority());
th1.start();
th2.start();
th3.start();
}
}