线程终止
线程终止是指线程的执行结束或者被强制终止。在Java中,线程终止有以下两种方式:
-
正常终止:当线程执行完所有的任务并正常退出时,线程就会终止。
-
异常终止:当线程因为未捕获的异常而终止时,线程就会以异常终止。
正常终止
正常终止是指当线程完成了所有的任务并正常退出时,线程就会终止。
这种方式可以通过以下两种方法实现:
run方法执行完成后,线程就会终止。
public class MyThread extends Thread {
@Override
public void run() {
// 线程执行的任务
}
}
MyThread thread = new MyThread();
thread.start(); // 启动线程
通过调用Thread类的interrupt()方法,让线程中断并终止。
interrupt()方法中断线程,线程就会终止
public class MyThread extends Thread {
@Override
public void run() {
try {
Thread.sleep(5000); // 线程休眠5秒
} catch (InterruptedException e) {
System.out.println("线程被中断");
}
}
}
MyThread thread = new MyThread();
thread.start(); // 启动线程
thread.interrupt(); // 中断线程
调用interrupt()方法并不会立即终止线程,而是会将线程的中断标志设置为true。如果在线程休眠期间调用了interrupt()方法,会抛出InterruptedException异常,并将中断标志清除。
异常终止
异常终止是指当线程因为未捕获的异常而终止时,线程就会以异常终止。
这种方式可以通过以下两种方法实现:
在run方法中抛出异常
public class MyThread extends Thread {
@Override
public void run() {
throw new RuntimeException("线程异常终止");
}
}
MyThread thread = new MyThread();
thread.start(); // 启动线程
}
在Thread.UncaughtExceptionHandler接口中捕获未捕获的异常
public class MyThread extends Thread {
@Override
public void run() {
throw new RuntimeException("线程异常终止");
}
}
public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t.getName() + "线程异常终止:" + e.getMessage());
}
}
public class Main {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
myThread.start();
}
}
创建了一个MyThread类,其中的run方法抛出一个RuntimeException异常。然后,我们实现了一个MyUncaughtExceptionHandler类,它实现了Thread.UncaughtExceptionHandler接口,并重写了uncaughtException方法,当线程抛出未捕获的异常时,将异常信息打印出来。
在Main类的main方法中,我们创建了一个MyThread对象,并将其UncaughtExceptionHandler设置为MyUncaughtExceptionHandler。然后,我们启动线程。
当线程抛出未捕获的异常时,MyUncaughtExceptionHandler的uncaughtException方法将被调用,并打印异常信息。这样,我们就可以处理未捕获的异常了。
线程的常用方法
- start():启动线程。
- run():线程的运行方法,需要自行重写。
- join():等待线程终止。
- interrupt():中断线程。
- isInterrupted():判断线程是否已中断。
- sleep():线程休眠一段时间。
- yield():暂停当前线程,让其他线程执行。
- setPriority():设置线程的优先级。
- getName():获取线程名称。
start()
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running.");
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
通过继承Thread类并重写run方法来实现多线程。使用start方法启动线程。
run()
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running.");
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.run();
}
}
直接调用run方法并不会创建一个新的线程,而是在当前线程中执行run方法。
join()
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running.");
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
MyThread thread = new MyThread();
thread.start();
thread.join();
System.out.println("Thread is terminated.");
}
}
使用join方法等待线程终止。在本例中,主线程等待MyThread线程终止后才能继续执行。
interrupt()
public class MyThread extends Thread {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread is interrupted.");
}
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
thread.interrupt();
}
}
使用interrupt方法中断线程。在本例中,MyThread线程休眠1秒钟,主线程调用interrupt方法中断线程。
isInterrupted()
public class MyThread extends Thread {
@Override
public void run() {
while (!isInterrupted()) {
System.out.println("Thread is running.");
}
System.out.println("Thread is interrupted.");
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
MyThread thread = new MyThread();
thread.start();
Thread.sleep(1000);
thread.interrupt();
}
}
使用isInterrupted方法判断线程是否已中断。在本例中,MyThread线程在不停地输出信息,直到被中断后输出“Thread is interrupted.”。
sleep()
方法签名为:
public static void sleep(long millis) throws InterruptedException
public class SleepDemo {
public static void main(String[] args) {
Thread t = new Thread(() -> {
try {
System.out.println("线程开始休眠");
Thread.sleep(3000);
System.out.println("线程休眠结束");
} catch (InterruptedException e) {
System.out.println("线程被中断");
}
});
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t.interrupt();
}
}
创建了一个新线程,使其在run()方法中调用sleep()方法休眠3秒钟。在主线程中,我们先让主线程休眠1秒钟,然后调用interrupt()方法中断新线程。当新线程被中断时,会抛出InterruptedException异常,我们在catch块中捕获该异常,并输出相应信息。 yield()方法
yield()
public class YieldTest {
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println("Thread1:" + i);
Thread.yield();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println("Thread2:" + i);
Thread.yield();
}
}
});
t1.start();
t2.start();
}
}
setPriority()
public class PriorityTest {
public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable());
Thread t2 = new Thread(new MyRunnable());
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
}
static class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}
getName()
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("当前线程的名称为:" + getName());
}
}
public class Main {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
System.out.println("当前主线程的名称为:" + Thread.currentThread().getName());
}
}
创建了一个继承自 Thread 类的 MyThread 子类。在 run() 方法中,我们使用 getName() 方法获取当前线程的名称并输出。