文章目录
- 前言
- 一、线程的生命周期
- 二、线程的操作方法
- 1.休眠
- 2.加入
- 3.中断
- 4.礼让
- 总结
前言
将线程看作一个生命的开始和结束,更好理解它各个状态的变化。同时该文会介绍操作线程的主要方法来控制线程的生命周期。这些方法的使用和线程生命周期的变化是密切相关的。
一、线程的生命周期
线程的生命周期有七种状态,分别为出生状态、就绪状态、运行状态、等待状态、休眠状态、阻塞状态和死亡状态。
出生状态:该线程实例化之后,调用start()方法之前,都是出生状态。
就绪状态:当调用start()方法之后,线程得到系统资源分配之前,都是就绪状态。
运行状态:得到系统资源分配后,都是运行状态(除非遇到操作线程的方法干预)。
等待状态:在运行状态下调用Thread类的wait()方法,线程此时处于等待状态。若要结束等待,需要调用Thread类的notify方法。结束所有线程的等待状态,调用Thread类的notifyAll()方法。
休眠状态:在运行状态下调用Thread类的sleep()方法,线程此时处于休眠状态。
阻塞状态:在运行状态下线程发起输入或输出的请求,在完成输入或输出动作前,线程都处于阻塞状态,无法恢复运行。
死亡状态:线程的run()方法执行完毕后,线程运行结束,线程死亡,释放系统资源。
二、线程的操作方法
1.休眠
所谓休眠,就是让线程暂停运行多长时间,多长时间靠输入的值决定。
使线程休眠的方法,就是调用sleep()方法。而sleep()方法需要一个int参数用来指定该线程休眠的时间。
sleep()方法的语法如下:
try{
Thread.sleep(int值);
//int值代表毫秒
}catch(InterruptedException){
e.printStrackTrace();
}
使用sleep()方法休眠线程时,需要注意两点:
(1)要用到try-catch语句,给sleep()方法报错。
(2)输入的int值对应该线程休眠几毫秒。
实操展示:
public class lon extends Thread{
public void run(){
for(int i=0;i<10;i++){
System.out.println(i);
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new lon().start();;
}
}
运行结果:
运行此线程时,本该一瞬间输出完0到9这几个数据,由于调用了Thread类的sleep()方法,线程每输出一个值就会休眠两秒。
2.加入
所谓加入,就是一个线程在运行的过程中,在某个点加入另一个线程。加入的线程运行完毕,死亡后,原本的线程再继续运行。
使线程加入,就要调用Thread类的join()方法。
join()方法的语法如下:
线程对象.join();
//这里是 线程对象 加入另外的正运行的线程对象
线程对象.join(long millis);
//该线程对象要过多少millis毫秒再加入线程中
实操展示:创建窗体,上面显示两个进度条,两个线程对应两个进度条,上面的进度条进度为50时,调用join()方法下方进度条线程加入上方进度条进程,两进程合二为一,下方加入的进程运行完毕后,上方进程再继续运行结束。
import java.awt.*;
import javax.swing.*;
public class lon extends JFrame{
private Thread threadA , threadB;
final JProgressBar progressBar = new JProgressBar();
final JProgressBar progressBar2 = new JProgressBar();
int count =0;
public static void init(JFrame jFrame,int width,int height){
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setSize(width, height);
jFrame.setVisible(true);
}
public lon(){
super();
getContentPane().add(progressBar,BorderLayout.NORTH);
getContentPane().add(progressBar2,BorderLayout.SOUTH);
progressBar.setStringPainted(true);
progressBar2.setStringPainted(true);
threadA = new Thread(new Runnable(){
//创建了一个新的Thread对象,并使用一个实现了Runnable接口的匿名内部类来初始化它。
int count=0;
public void run(){
while (true) {
progressBar.setValue(++count);
try {
Thread.sleep(100);
if(count==50){
threadB.join();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
threadA.start();
threadB=new Thread(new Runnable() {
int count =0;
public void run(){
while (true) {
progressBar2.setValue(++count);
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
if (count==100) {
break;
}
}
}
});
threadB.start();
}
public static void main(String[] args) {
init(new lon(), 100, 100);
}
}
运行结果:
如上图所示,开发时,只需要再一个线程的run()方法中对应的位置调用join()方法引入另一个进程,就会实现中途插入新进程,运行完后,继续旧进程的效果。
3.中断
所谓中断,就是让线程在指定的运行地方中断运行。和线程休眠不同的是,没有固定时间来恢复运行。
使线程中断,就要调用Thread类中的interrupt()方法,使得线程离开了run()方法。结束线程的同时,程序也会抛出 InterruptedException异常,要用try-catch语句捕获异常,开发者在catch语句中要写好对应的处理代码。
interrupted()方法的语法如下:
try{
线程对象.interrupt();
}catch(InterruptedException e){
System.out.println("线程被中断");
}
实操展示:
import java.awt.*;
import javax.swing.*;
public class lon extends JFrame {
private Thread threadA;
final JProgressBar progressBar = new JProgressBar();
int count = 0;
public static void init(JFrame jFrame, int width, int height) {
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setSize(width, height);
jFrame.setVisible(true);
}
public lon() {
super();
getContentPane().add(progressBar, BorderLayout.NORTH);
progressBar.setStringPainted(true);
threadA = new Thread(new Runnable() {
int count = 0;
public void run() {
while (true) {
progressBar.setValue(++count);
try {
Thread.sleep(100);
if (count == 50) {
threadA.interrupt(); // 中断当前线程
}
} catch (InterruptedException e) {
System.out.println("线程被中断");
e.printStackTrace();
break; // 退出循环
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
threadA.start();
}
public static void main(String[] args) {
init(new lon(), 100, 100);
}
}
运行结果:
由上图所示,当一个线程调用了interrupt()方法,这个线程就会中止运行。若想恢复运行,需要在catch语句中自行编写对应功能的代码。
4.礼让
所谓礼让,就是暗示线程在某一运行过程中可以暂时将系统资源礼让给其他线程。这个操作线程的方法有个弊端,不能保证运行至代码处,该线程一定会礼让,因为操作系统给各个线程自动分配时间片,有些操作系统,线程的调度不可预测。所以说线程的礼让,打个比方就是,公交车上年轻人给老人让座,但不一定每个年轻人都让座。
使线程礼让,就要调用Thread类中的yield()方法。该方法使得线程比其他相同级别的线程,更优先的资源分配。
yield()方法的语法如下:
线程对象.yield();
礼让的内容想要深入了解的小伙伴可以自行网上搜索。
总结
以上就是操作线程的方法的介绍,本文仅仅简单介绍了操作线程方法的使用,而熟练地使用线程开发项目是一个徐徐渐进,日进斗金的功夫活。文章中有不足或要补充的内容,欢迎小伙伴们在评论区中留言。