线程系列传送门:
1、join方法
作用:执行该方法的线程进入阻塞状态,直到调用该方法的线程结束后再由阻塞转为就绪状态。
注意:
- 线程对象在调用join方法前必须先调用start方法,否则该线程永远不会进入执行状态。
- 线程A执行“已死”线程B所调用的jion方法,则线程A不会阻塞。
实例(分析于代码注释):
public class Test {
public static void main(String[] args) {
CountThread countThread = new CountThread();
TimeThread timeThread = new TimeThread(countThread);
countThread.start();
timeThread.start();
}
}
class TimeThread extends Thread{
CountThread countThread;
public TimeThread(CountThread countThread) {
this.countThread = countThread;
}
@Override
public void run() {
try {
countThread.join();//由于在TimeThread线程中执行该方法,countThread线程的对象调用该方法,因此timeThread线程阻塞countThread线程执行,直到countThread线程执行结束
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i = 0;i<50;i++) {
System.out.println("时间线程____"+i);
}
}
}
class CountThread extends Thread{
@Override
public void run() {
for(int i = 0;i<50;i++) {
System.out.println("计数线程"+i);
}
}
}
2、interrupt方法
作用:结束线程在调用Object类的wait方法或该类的join方法、sleep方法过程中的阻塞状态,并在调用wait、join和sleep方法处产生InterruptedException异常。
实例:
public class Test {
public static void main(String[] args) {
CountThread countThread = new CountThread();
TimeThread timeThread = new TimeThread(countThread);
countThread.start();
timeThread.start();
timeThread.interrupt(); //时间线程调用interrupt方法结束阻塞状态,必定先输出50次结果
}
}
class TimeThread extends Thread{
CountThread countThread;
public TimeThread(CountThread countThread) {
this.countThread = countThread;
}
@Override
public void run() {
try {
countThread.join();//时间线程中执行join方法,时间线程阻塞;计数线程调用join方法,计数线程优先执行
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i = 0;i<50;i++) {
System.out.println("时间线程____"+i);
}
}
}
class CountThread extends Thread{
@Override
public void run() {
try {
sleep(1000);//让计数线程阻塞,便于证明时间线程调用interrupt方法确实结束了阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i = 0;i<50;i++) {
System.out.println("计数线程"+i);
}
}
}
3、currentThread方法
作用:返回当前正在执行的线程的对象。
实例:
import java.util.Date;
public class Test {
public static void main(String[] args) {
TimeThread timeThread = new TimeThread();
timeThread.start();
Thread thread = Thread.currentThread();//获取当前正在执行的线程并返回该线程对象,当前线程为main方法的主线程
System.out.println(thread);
System.out.println(timeThread);//打印时间线程的信息(名称,优先等级,线程组)
}
}
class TimeThread extends Thread{
public TimeThread() {
super("时间线程");//Thread重写了super方法,可用于命名线程对象
}
@Override
public void run() {
printTime();
}
public static void printTime() {
Thread thread = Thread.currentThread();//获取当前正在执行的线程,返回该线程的对象
System.out.println(thread);//打印现在执行线程的信息
System.out.println(thread.getName()+new Date());
}
}
4、isAlive方法
作用:判定该线程是否处于就绪、运行或阻塞状态,如果是则返回true,否则返回false。
实例:
public class Test {
public static void main(String[] args) {
Thread thread = Thread.currentThread();//获取当前执行线程(即执行main方法的主线程)的对象
new TimeThread(thread).start();//将主线程对象作为参数传入创建的时间线程对象
System.out.println("main线程状态:"+thread.isAlive());//检测执行main方法的主线程的存活状态
}
}
class TimeThread extends Thread{
private Thread thread;
public TimeThread(Thread thread){
this.thread = thread;
}
@Override
public void run() {
try {
sleep(1000);//设定时间线程阻塞1秒,目的是让main方法的线程结束(关闭)
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println("main线程状态:"+thread.isAlive());//再次检测执行main方法的主线程的存活状态
}
}
5、setDaemon方法
作用:用于将一个尚未调用线程start方法的线程设置为守护线程。守护线程随着最后一个非守护线程的终止而终止。守护线程主要用于为其他线程的运行提供服务(Java中的垃圾回收机制就是守护线程),这种线程属于创建它的线程。
实例:
public class Test {
public static void main(String[] args) {
CounterThread counterThread = new CounterThread();
counterThread.setDaemon(true);//将计数线程设置为守护线程,该线程会随着最后一个非守护线程的关闭而关闭
counterThread.start();
try {
Thread.sleep(1);//设置main主线程阻塞1秒, 让计数线程开始执行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class CounterThread extends Thread {
public void run() {
int i=1;
while(true){
System.out.println("计数器:"+i);//该循环会在1毫秒后结束,然后与主线程抢占CPU资源,一旦主线程结束,则计数线程(守护线程)也随之结束,进程结束
i++;
}
}
}
其它方法
1、void start():使该线程开始启动,Java 虚拟机负责调用该线程的 run() 方法。多次启动一个线程是非法的。
2、void sleep(long millis):Thread类静态方法,线程进入阻塞状态,在指定时间(单位为毫秒)到达之后进入就绪状态(Runnable),而非立即进入执行状态。
3、void yield():静态方法,当前线程放弃占用CPU资源,回到就绪状态,使其他优先级不低于此线程的线程有机会被执行。 (注意:yield方法实际作用不大,因为即使当前线程放弃CPU资源,但在下一次抢占资源时,该线程仍可能成功抢占CPU资源)
4、void setPriority(int newPriority):设置当前线程的优先级,线程优先级越高,线程获得执行的次数越多,Java线程的优先级用整数表示,取值范围是1~10,Thread类有以下三个静态常量:
- static int MAX_PRIORITY 最高优先级值为10
- static int NORM_PRIORITY 默认优先级值为5
- static int MIN_PRIORITY 最低优先级值为1
注意:同一个线程类创建的多个线程,线程优先级越高的线程获得的执行次数极有可能越多;但是不同线程类创建的线程,线程优先级越高,执行次数不一定越多,这个run方法的代码复杂度有关。
5、int getPriority():获得当前线程的优先级。