1. 概述
在多线程编程中,Thread类是一个核心类。它提供了一系列的方法来创建、控制和管理线程,使得我们可以更加方便地编写高效、可伸缩的多线程应用。
本文将详细介绍Thread类的各种方法及其使用方法。
2. 创建Thread类实例
创建Thread类实例有两种基本方法:
2.1 继承Thread类
如果要创建一个新的线程,可以通过继承Thread类来实现。具体步骤如下:
创建一个新类,继承自Thread类。
在新类中实现run()函数,run()函数是线程的主要执行体。
创建新类的实例并调用start()函数启动线程。
class MyThread : public Thread {
public:
void run() {
// 线程执行的主体代码
}
};
int main() {
MyThread myThread;
myThread.start(); // 启动线程
return 0;
}
使用继承的方式可以方便地重写线程主体函数,并且可以自定义一些成员变量和成员函数。
2.2 实现Runnable接口
另一种创建Thread类实例的方法是实现Runnable接口。具体步骤如下:
创建一个新类实现Runnable接口,并实现run()函数,run()函数是线程的主要执行体。
创建Runnable实例,以Runnable为参数创建Thread实例。
调用start()函数启动线程。
class MyRunnable : public Runnable {
public:
void run() {
// 线程执行的主体代码
}
};
int main() {
MyRunnable myRunnable;
Thread myThread(myRunnable);
myThread.start(); // 启动线程
return 0;
}
使用实现Runnable接口的方式可以让类继续继承其他类,提高了代码的灵活性。
3. 启动线程
启动线程的方法是调用start()函数。start()函数会启动线程并在一个新的操作系统线程中执行run()函数。
注意:一个线程只能启动一次,如果多次调用start()函数会抛出ThreadStateException异常。
Thread myThread;
myThread.start();
4. 等待线程
4.1 join()
join()函数用于等待一个线程结束。如果当前线程调用了join()函数等待另外一个线程,那么当前线程会一直阻塞,直到待等待的线程完成执行。
join()函数的语法如下:
void join();
例如:
Thread myThread;
myThread.start();
myThread.join(); // 等待myThread执行完毕
4.2 join(long millis)
join(long millis)函数也用于等待一个线程结束,但是它允许等待一定的时间,如果线程没有在规定时间内结束,则join()函数返回。
join(long millis)函数的语法如下:
void join(long millis);
例如:
Thread myThread;
myThread.start();
myThread.join(1000); // 等待myThread执行1000毫秒
4.3 join(long millis, int nanos)
join(long millis, int nanos)函数用于等待一个线程结束,可以指定等待时间的毫秒数和纳秒数。方法和join(long millis)相似,只是精度更高一些。
join(long millis, int nanos)函数的语法如下:
void join(long millis, int nanos);
例如:
Thread myThread;
myThread.start();
myThread.join(1, 500000000); // 等待myThread执行1.5秒
5. 中断线程
中断线程的方法是调用interrupt()函数。当线程被中断时,它的中断标志会被设置为true。
注意:interrupt()函数只是设置线程中断标志,如果线程没有处理中断请求,则中断请求不会导致线程真正的中断。
Thread myThread;
myThread.interrupt();
6. 线程挂起和唤醒
线程挂起的方法是调用suspend()函数。当线程挂起时,它的执行被暂停,但是线程对象并没有被销毁,可以通过resume()函数唤醒线程。
注意:suspend()函数容易导致死锁,如果使用不当,可能会导致应用程序无法响应。在Java SE 2之后,推荐使用Object.wait()和Object.notify()来代替suspend()和resume()。
Thread myThread;
myThread.suspend(); // 挂起线程
myThread.resume(); // 唤醒线程
7. 线程优先级
线程优先级可以通过setPriority()函数设置。任何线程都有一个优先级,当有多个线程竞争CPU时,优先级高的线程会被更频繁地执行。
线程的优先级是一个整数,取值范围为1~10,其中1为最低优先级,10为最高优先级。默认的优先级为5。
Thread myThread;
myThread.setPriority(8); // 设置优先级为8
8. 获取当前线程
可以通过Thread::currentThread()函数获取当前正在执行的线程对象。此函数是静态的。
Thread* currentThread = Thread::currentThread(); // 获取当前线程对象
9. 线程休眠
线程休眠的方法是调用sleep()函数。当线程休眠时,它的执行被暂停,但是线程对象并没有被销毁,可以通过Thread.interrupt()中断线程的休眠状态。
Thread::sleep(1000); // 让线程休眠1秒
10. 线程状态
Thread类提供了一个getState()函数来获取线程状态,返回类型为Thread::State。Thread::State是一个枚举类型,包括以下值:
NEW:初始状态,尚未启动
RUNNABLE:正在被运行线程调用或准备好被系统运行
BLOCKED:线程阻塞等待监视器锁
WAITING:等待另一个线程执行特定操作
TIMED_WAITING:等待另一个线程执行特定操作的指定时间
TERMINATED:已经完成执行
Thread myThread;
Thread::State state = myThread.getState(); // 获取线程状态
11. 总结
Thread类提供了一系列方法来创建、控制和管理线程。它是多线程编程中一个核心的类。在使用Thread类的时候应该注意线程安全性,并且根据具体的业务需求,灵活运用继承和实现Runnable接口两种方式来创建线程。