线程中的常用方法
join方法
join方法:执行该方法的线程进入阻塞状态,直到调用该方法的线程结束后再由阻塞转为就绪状态。
例子1
package test;
import java.util.Date;
public class Test2 {
public static void main(String[] args) {
TimesThread timesThread = new TimesThread();
timesThread.start();
CounterThread counterThread = new CounterThread(timesThread);
new Thread(counterThread).start();
}
}
class CounterThread implements Runnable{
TimesThread timesThread;
String counterThread = "计数器线程";
public CounterThread(TimesThread timesThread){
this.timesThread=timesThread;
}
@Override
public void run() {
for (int i=1;i<=5;i++){
System.out.println(counterThread+"运行第"+i+"次");
if(i==2){
try {
timesThread.join();//执行该方法的是计数器线程(阻塞),调用该方法的是时间线程(由抢占式执行变为优先执行,仅就这两个线程而言)
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class TimesThread extends Thread{
String timesThread = "时间线程";
@Override
public void run() {
for (int i=1;i<=5;i++){
System.out.println(timesThread+":"+new Date());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果
计数器线程运行第1次
时间线程:Sun Feb 07 16:05:24 GMT+08:00 2021
计数器线程运行第2次
时间线程:Sun Feb 07 16:05:25 GMT+08:00 2021
时间线程:Sun Feb 07 16:05:26 GMT+08:00 2021
时间线程:Sun Feb 07 16:05:27 GMT+08:00 2021
时间线程:Sun Feb 07 16:05:28 GMT+08:00 2021
计数器线程运行第3次
计数器线程运行第4次
计数器线程运行第5次
注意: 线程对象在调用join方法前必须先调用start方法,否则该线程永远不会进入执行状态。
interrupt方法
interrupt方法:结束线程在调用Object类的wait方法或该类的join方法、sleep方法过程中的阻塞状态,并在调用wait、join和sleep方法处产生InterruptedException异常。
例子2
package test;
import java.util.Date;
public class Test2 {
public static void main(String[] args) {
TimesThread timesThread = new TimesThread();
timesThread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
timesThread.interrupt();//调用此方法之后,线程打断阻塞状态继续执行
}
}
class TimesThread extends Thread{
String timesThread = "时间线程";
@Override
public void run() {
System.out.println(timesThread+":"+new Date());
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
System.out.println("捕获异常");
e.printStackTrace();
}
//正常来讲两个输出时间应该相差30秒
System.out.println(timesThread+":"+new Date());
}
}
运行结果
时间线程:Sun Feb 07 16:21:08 GMT+08:00 2021
捕获异常
时间线程:Sun Feb 07 16:21:09 GMT+08:00 2021
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at test.TimesThread.run(Test2.java:60)
currentThread方法
currentThread方法:返回当前正在执行的线程对象。
package test;
public class Test2 {
public static void main(String[] args) {
TimesThread timesThread = new TimesThread();
System.out.println("########"+timesThread);//返回创建的线程对象
timesThread.start();
timesThread.main();
}
}
class TimesThread extends Thread{
public TimesThread(){
super("时间线程");//为线程取名字
}
@Override
public void run() {
main();
}
void main(){
Thread thread = Thread.currentThread();//返回正在执行的线程对象
System.out.println("@@@@@@@@"+thread);
}
}
运行结果
########Thread[时间线程,5,main]
主线程:@@@@@@@@Thread[main,5,main]
时间线程:@@@@@@@@Thread[时间线程,5,main]
isAlive方法
isAlive方法:判定该线程是否处于就绪、运行或阻塞状态,如果是则返回true,否则返回false。
例子3
package test;
public class Test2 {
public static void main(String[] args) {
Thread thread = Thread.currentThread();
new PrintThread(thread).start();
System.out.println("main线程状态:"+thread.isAlive());//运行结果为true,此时线程处于就绪状态或者运行状态
}
}
class PrintThread extends Thread{
private Thread thread;
public PrintThread(Thread thread){
this.thread = thread;
}
@Override
public void run() {
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println("main线程状态:"+thread.isAlive());//阻塞三秒后,线程处于运行完毕状态,运行结果为false,意思是线程已经死了。
//注意,main方法中启动的线程可能晚于主线程结束。
}
}
运行结果
out:main线程状态:true
err:main线程状态:false
注意:线程A执行“已死”线程B所调用的jion方法,则线程A不会阻塞。
setDaemon方法
setDaemon方法:用于将一个尚未调用线程start方法的线程设置为守护线程。守护线程主要用于为其他线程的运行提供服务(Java中的垃圾回收机制就是守护线程),这种线程属于创建它的线程。
注意:1、守护线程随着最后一个非守护线程的终止而终止。
2、进程中所启动的其他非守护线程不会随着某一个非守护线程的结束而结束。
3、进程随着最后一个非守护线程的结束而结束。
其他方法
- void start():使该线程开始启动,Java 虚拟机负责调用该线程的 run() 方法。多次启动一个线程是非法的。
- void sleep(long millis):Thread类静态方法,线程进入阻塞状态,在指定时间(单位为毫秒)到达之后进入就绪状态(Runnable),而非立即进入执行状态。
- void yield():静态方法,当前线程放弃占用CPU资源,回到就绪状态,使其他优先级不低于此线程的线程有机会被执行。
- void setPriority(int newPriority):设置当前线程的优先级,线程优先级越高,线程获得执行的次数越多,Java线程的优先级用整数表示,取值范围是1~10,Thread类有以下三个静态常量:
- static int MAX_PRIORITY 最高优先级值为10;
- static int NORM_PRIORITY 默认优先级值为5;
- static int MIN_PRIORITY 最低优先级值为1;
- 注意:同一个线程类创建的多个线程,线程优先级越高的线程获得的执行次数极有可能越多;但是不同线程类创建的线程,线程优先级越高,执行次数不一定越多,这个run方法的代码复杂度有关。
- int getPriority():获得当前线程的优先级。