# Java多线程创建全解析:从Thread到Callable及核心方法剖析
多线程编程是现代软件开发中不可或缺的重要技术,它能够有效提升程序性能,改善用户体验。Java作为一门成熟的企业级编程语言,提供了完整而强大的多线程支持。本文将全面解析Java中线程创建的多种方式,并深入探讨Thread类的核心方法。
## 线程创建的基本方式
### 继承Thread类
继承Thread类是最基础的线程创建方式,通过重写run方法定义线程执行逻辑。
```java
public class MyThread extends Thread {
private String threadName;
public MyThread(String name) {
this.threadName = name;
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(threadName + " 运行: " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(threadName + " 被中断");
}
}
System.out.println(threadName + " 执行结束");
}
}
// 使用示例
public class ThreadDemo {
<"phjk.jiebaobifen.com">
<"pmar.jiebaobifen.com">
<"junv.jiebaobifen.com">
public static void main(String[] args) {
MyThread thread1 = new MyThread("线程A");
MyThread thread2 = new MyThread("线程B");
thread1.start();
thread2.start();
}
}
```
这种方式简单直观,但由于Java的单继承限制,一旦继承了Thread类就无法再继承其他类,这在设计上存在一定局限性。
### 实现Runnable接口
实现Runnable接口是更为灵活的线程创建方式,它克服了单继承的限制,允许类在继承其他类的同时实现多线程。
```java
public class MyRunnable implements Runnable {
private String threadName;
public MyRunnable(String name) {
this.threadName = name;
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(threadName + " 运行: " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(threadName + " 被中断");
}
}
System.out.println(threadName + " 执行结束");
}
}
// 使用示例
public class RunnableDemo {
<"rwvh.jiebaobifen.com">
<"gjiw.jiebaobifen.com">
<"lxtv.jiebaobifen.com">
public static void main(String[] args) {
Thread thread1 = new Thread(new MyRunnable("线程A"));
Thread thread2 = new Thread(new MyRunnable("线程B"));
thread1.start();
thread2.start();
}
}
```
### 实现Callable接口
Callable接口是Java 5中引入的增强型线程创建方式,与Runnable相比,Callable可以返回执行结果,并能抛出异常。
```java
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class MyCallable implements Callable<String> {
private String threadName;
public MyCallable(String name) {
this.threadName = name;
}
@Override
public String call() throws Exception {
StringBuilder result = new StringBuilder();
for (int i = 0; i < 5; i++) {
result.append(threadName).append(" 运行: ").append(i).append("\n");
Thread.sleep(500);
}
result.append(threadName).append(" 执行结束");
return result.toString();
}
}
// 使用示例
public class CallableDemo {
<"aifw.jiebaobifen.com">
<"lfyb.jiebaobifen.com">
<"nbix.jiebaobifen.com">
public static void main(String[] args) {
try {
FutureTask<String> futureTask1 = new FutureTask<>(new MyCallable("线程A"));
FutureTask<String> futureTask2 = new FutureTask<>(new MyCallable("线程B"));
Thread thread1 = new Thread(futureTask1);
Thread thread2 = new Thread(futureTask2);
thread1.start();
thread2.start();
// 获取线程执行结果
String result1 = futureTask1.get();
String result2 = futureTask2.get();
System.out.println("线程A结果:\n" + result1);
System.out.println("线程B结果:\n" + result2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
## Thread类核心方法详解
### 线程生命周期管理方法
**start()方法**
start()方法用于启动线程,使其进入就绪状态。需要注意的是,直接调用run()方法不会创建新线程,而是在当前线程中执行。
```java
public class StartExample {
<"ydpj.jiebaobifen.com">
<"twmo.jiebaobifen.com">
<"sojx.jiebaobifen.com">
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("线程ID: " + Thread.currentThread().getId());
System.out.println("线程名称: " + Thread.currentThread().getName());
});
System.out.println("主线程ID: " + Thread.currentThread().getId());
thread.start(); // 创建新线程执行
// thread.run(); // 在当前线程执行,不会创建新线程
}
}
```
**sleep()方法**
sleep()方法使当前线程暂停执行指定的时间,但不会释放锁。
```java
public class SleepExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("计数: " + i);
try {
Thread.sleep(1000); // 暂停1秒
} catch (InterruptedException e) {
System.out.println("线程被中断");
}
}
});
thread.start();
}
}
```
**yield()方法**
yield()方法提示调度器当前线程愿意让出CPU,但调度器可以忽略这个提示。
```java
public class YieldExample {
<"mhll.jiebaobifen.com">
<"mcmj.jiebaobifen.com">
<"egaw.jiebaobifen.com">
public static void main(String[] args) {
Thread producer = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("生产者生产: " + i);
Thread.yield(); // 让出CPU给消费者
}
});
Thread consumer = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("消费者消费: " + i);
Thread.yield(); // 让出CPU给生产者
}
});
producer.start();
consumer.start();
}
}
```
### 线程控制方法
**join()方法**
join()方法等待调用该方法的线程终止,常用于线程间的协调。
```java
public class JoinExample {
public static void main(String[] args) {
Thread worker1 = new Thread(() -> {
try {
Thread.sleep(2000);
System.out.println("工作者1完成任务");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread worker2 = new Thread(() -> {
try {
Thread.sleep(1000);
System.out.println("工作者2完成任务");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
worker1.start();
worker2.start();
try {
System.out.println("等待所有工作者完成任务...");
worker1.join();
worker2.join();
System.out.println("所有工作者都已完成任务,主线程继续执行");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
```
**interrupt()方法**
interrupt()方法用于中断线程,但需要被中断的线程配合检查中断状态。
```java
public class InterruptExample {
<"uecm.jiebaobifen.com">
<"hgco.jiebaobifen.com">
<"szek.jiebaobifen.com">
public static void main(String[] args) {
Thread worker = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("工作者正在运行...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("工作者被中断,退出执行");
Thread.currentThread().interrupt(); // 重新设置中断状态
}
}
});
worker.start();
try {
Thread.sleep(3000);
worker.interrupt(); // 3秒后中断工作者线程
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
```
### 线程状态检查方法
**isAlive()方法**
检查线程是否处于活动状态。
```java
public class AliveExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("启动前是否存活: " + thread.isAlive());
thread.start();
System.out.println("启动后是否存活: " + thread.isAlive());
try {
thread.join();
System.out.println("执行完成后是否存活: " + thread.isAlive());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
```
## 线程优先级和守护线程
### 线程优先级
Java线程的优先级范围是1-10,默认优先级为5。
```java
public class PriorityExample {
public static void main(String[] args) {
Thread lowPriorityThread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("低优先级线程执行");
}
});
Thread highPriorityThread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("高优先级线程执行");
}
});
lowPriorityThread.setPriority(Thread.MIN_PRIORITY); // 优先级1
highPriorityThread.setPriority(Thread.MAX_PRIORITY); // 优先级10
lowPriorityThread.start();
highPriorityThread.start();
}
}
```
### 守护线程
守护线程是为其他线程提供服务的线程,当所有非守护线程结束时,守护线程会自动终止。
```java
public class DaemonExample {
<"uxre.jiebaobifen.com">
<"vlbm.jiebaobifen.com">
<"ydlw.jiebaobifen.com">
public static void main(String[] args) {
Thread daemonThread = new Thread(() -> {
while (true) {
System.out.println("守护线程在运行...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread userThread = new Thread(() -> {
for (int i = 0; i < 3; i++) {
System.out.println("用户线程执行: " + i);
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("用户线程执行结束");
});
daemonThread.setDaemon(true); // 设置为守护线程
daemonThread.start();
userThread.start();
}
}
```
## 总结
Java多线程编程提供了丰富的API支持,从基础的Thread类继承到灵活的Runnable接口实现,再到功能更强的Callable接口,每种方式都有其适用场景。Thread类的核心方法为线程的生命周期管理、状态控制和协调提供了完善的支持。
在实际开发中,选择哪种线程创建方式需要根据具体需求来决定。对于简单的任务,可以使用Thread或Runnable;对于需要返回结果或处理异常的任务,Callable是更好的选择。同时,合理使用Thread类的各种方法,能够编写出更加健壮和高效的多线程程序。
理解线程的优先级、守护线程特性以及各种线程控制方法,有助于开发出更加符合业务需求的多线程应用。多线程编程虽然强大,但也需要注意线程安全、死锁等问题,这些都需要在实际开发中给予充分重视。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/19545/viewspace-3102283/ ,如需转载,请注明出处,否则将追究法律责任。