个人中心:SueWakeup
系列专栏:学习Java
个性签名:保留赤子之心也许是种幸运吧
目录
一个线程的生命周期
线程终止的原因
线程的方法
Thread 类的静态方法
1. 设置线程的优先级与休眠
2. 中断线程
3. 让出线程
4. 守护线程
5. 线程插队
注:手机端浏览本文章可能会出现 “目录”无法有效展示的情况,请谅解,点击侧栏目录进行跳转
一个线程的生命周期
线程是一个动态执行的过程,它也有一个从产生到死亡的过程。
- 新建状态(New):使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程
- 运行状态(Runnable):运行中的线程,已经调用 start() 方法,线程正在或即将执行 run() 方法
- 终止状态(Terminated):线程已终止,因为 run() 方法执行完毕
- 阻塞状态(Blocked):运行中的线程,在等待竞争锁时,被阻塞,暂不执行
- 等待状态(Waiting):运行中的线程因为 sleep() 或 join() 等方法调用,进入等待
- 计时等待状态(Timed Waiting):运行中的线程,因为执行 sleep(X ms) 或 join(X ms)等方法,进入计时等待
线程终止的原因
- 正常终止:run() 方法执行到 return 语句返回
- 意外终止:run() 方法因为未捕获的异常导致线程终止
- 对某个线程的 Thread 实例调用 stop() 方法强制终止(不推荐)
线程的方法
序号 | 方法描述 |
---|---|
1 | public void start() JVM 调用该线程的 run() 方法 |
2 | public void run() 如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run方法 否则,该方法不执行任何操作并返回 |
3 | public final void setName(String name) 改变线程名称 |
4 | public final void setPriority(int priority) 更改线程的优先级 |
5 | public final void setDaemon(boolean on) 将该线程标记为守护线程或用户线程 |
6 | public final void join(long millisec) 等待该线程终止的时间最长为 millis 毫秒 |
7 | public void interrupt() 中断线程 |
8 | public final boolean isAlive() 测试线程是否处于活动状态 |
Thread 类的静态方法
序号 | 方法描述 |
---|---|
1 | public static void yield() 暂停当前正在执行的线程对象,并执行其他线程。 |
2 | public static void sleep(long millisec) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),受系统计时器和调度程序精度和准确性的影响。 |
3 | public static boolean holdsLock(Object x) 当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true。 |
4 | public static Thread currentThread() 返回对当前正在执行的线程对象的引用。 |
5 | public static void dumpStack() 将当前线程的堆栈跟踪打印至标准错误流。 |
1. 设置线程的优先级与休眠
class MyTask implements Runnable{
@Override
public void run() {
char c ='6';
for(int i=1;i<=26;i++,c++){
//线程的休眠
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
System.out.println(Thread.currentThread().getName()+":"+c);
}
}
}
/*
线程的设置
*/
MyTask task = new MyTask();
Thread t1 = new Thread(task, "线程1");
Thread t2 = new Thread(task);
t2.setName("线程2");
//设置线程的优先级(起参考作用)
t1.setPriority(1);
t2.setPriority(10);
t1.start();
t2.start();
解读:
- 通过 Thread 对象 t1 / t2 的 setPriority() 方法设置线程优先级,1为最低优先级,10为最高优先级
- 注释部分为线程的休眠部分 Thread.sleep(1000):休眠1秒
2. 中断线程
//线程中断
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("子线程开始执行");
//Thread.sleep();方法可以自动监听中断状态
// try {
// Thread.sleep(6000);//子线程休眠6000豪秒
// } catch (InterruptedException e) {
// System.out.println("子线程中断");
// }
//检查当前线程是否处于中断
while (!Thread.currentThread().isInterrupted()){
System.out.println("塔塔开...");
}
System.out.println("子线程结束执行");
}
});
t.start();
try {
Thread.sleep(3000);//主线程休眠3000毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
//设置子线程t的中断状态
t.interrupt();
System.out.println("main主线程结束执行......");
解读:
- 通过 Thread.currentThread().isInterrupted() 方法检查当前线程是否处于中断状态
- 如果取消注释掉的部分,子线程会在休眠期间被中断
3. 让出线程
//线程的让出
Thread t1 =new Thread(new Runnable() {
@Override
public void run() {
char c='a';
for(int i=1;i<27;i++,c++){
System.out.println(Thread.currentThread().getName()+":"+c);
}
}
},"子线程1");
Thread t2 =new Thread(new Runnable() {
@Override
public void run() {
for(char i ='a';i<'z';i++){
//让出线程cpu处理器的执行
Thread.yield();
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
},"子线程2");
t1.start();
t2.start();
解读:
- 在 t1 线程的 run() 方法中每次循环打印一个字母,t2 线程会在每次循环中,调用 Thread.yield() 方法来让出线程的 CPU 执行权
- 线程 t1 和 t2 会交替执行,但是因为 t2 使用了 Thread.yield() 方法,增加了线程切换的可能性,影响线程的效率
4. 守护线程
//守护线程
Thread t1 =new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程结束执行!");
}
},"子线程1");
//设置为守护线程
t1.setDaemon(true);
t1.start();
//main主线程在子线程休眠结束前恢复
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Game Over~~");
解读:
- 通过调用 t1.setDaemon(true) 将线程 t1 设置为守护线程,当所有非守护线程结束时,守护线程会随之结束
5. 线程插队
class MyTask1 implements Runnable{
@Override
public void run() {
char c ='一';
for(int i=1;i<27;i++,c++){
System.out.println(Thread.currentThread().getName()+":"+c);
}
}
}
//子线程的插队
MyTask1 task = new MyTask1();
Thread t1 = new Thread(task,"子线程1");
t1.start();
try {
t1.join(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程执行结束,完成执行");
解读:
- 调用 t1.join(1000) 方法,让主线程等待 t1 线程执行完毕或等待一定的时间,在等待 t1 线程执行完毕或超时后,主线程才开始执行