面试高频题:
在 Java 后端开发的面试中,我们经常被问到这样的一道题目:
Java 中创建线程的方式有哪些?
我们知道 Java 使用 Thread 类代表线程,所有的线程对象都必须是 Thread 类或其子类的实例。本文分享以下四种 Java 创建线程的方式:
1. 继承 Thread 类创建线程;
2. 实现 Runnable 接口创建线程;
3. 使用 Callable 和 Future 创建线程;
4. 使用线程池,例如:用 Executor 框架创建线程池。
1. 继承 Thread 类创建线程
通过继承 Thread 类来创建线程的一般步骤如下:
1. 定义一个 Thread 类的子类,重写 run() 方法,将相关逻辑实现,run() 方法就是线程要执行的业务逻辑方法;
2. 创建自定义的线程子类对象;
3. 调用子类实例的 start() 方法来启动线程。
-
案例:
package com.offer.manongqiuzhi.thread;
/**
* @author pcwl
*/
public class MyThread extends Thread{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " from 码农求职小助手");
}
}
public class MyThreadTest {
public static void main(String[] args) {
// 创建线程
MyThread thread = new MyThread();
// 启动线程
thread.start();
}
}
运行结果:
2. 实现 Runnable 接口创建线程
通过实现 Runnable 接口创建线程一般步骤如下:
1. 定义 Runnable 接口实现类 MyRunnable,并重写 run() 方法;
2. 创建 MyRunnable 实例 runnable,以 runnable 作为 target 创建 Thead 对象,该 Thread 对象才是真正的线程对象;
3. 调用线程对象的 start() 方法。
-
案例:
package com.offer.manongqiuzhi.thread;
/**
* @author pcwl
*/
public class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " from 码农求职小助手");
}
}
public class MyRunnableTest {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
// 创建线程
Thread thread = new Thread(myRunnable);
// 启动线程
thread.start();
}
}
运行结果:
3. 使用 Callable 和 Future 创建线程
和 Runnable 接口不一样,Callable 接口提供了一个 call() 方法作为线程执行体,call() 方法比 run() 方法功能要强大,比如:call() 方法可以有返回值、call() 方法可以声明抛出异常。
Java5 提供了 Future 接口来代表 Callable 接口里 call() 方法的返回值,并且为 Future 接口提供了一个实现类 FutureTask,这个实现类既实现了 Future 接口,还实现了 Runnable 接口,因此可以作为 Thread 类的 target。在 Future 接口里定义了几个公共方法来控制它关联的 Callable 任务。
使用 Callable 和 Future 创建线程的一般步骤如下:
1. 创建实现 Callable 接口的类 myCallable;
2. 以 myCallable 为参数创建 FutureTask 对象;
3. 将 FutureTask 作为参数创建 Thread 对象;
4. 调用线程对象的 start() 方法。
-
案例:
package com.offer.manongqiuzhi.thread;
import java.util.concurrent.Callable;
/**
* @author pcwl
*/
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() + " from 码农求职小助手");
return 99;
}
}
public class MyCallableTest {
public static void main(String[] args) {
FutureTask<Integer> futureTask = new FutureTask<>(new MyCallable());
// 创建线程
Thread thread = new Thread(futureTask);
// 启动线程
thread.start();
// 结果返回
try {
Thread.sleep(1000);
System.out.println("返回的结果是:" + futureTask.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果:
4. 使用线程池创建线程
Executors 提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService 接口。
主要有四种:
1. newFixedThreadPool
2. n
ewCachedThreadPool
3. n
ewSingleThreadExecutor
4. newScheduledThreadPool
-
案例:
package com.offer.manongqiuzhi.thread;
/**
* @author pcwl
*/
public class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " from 码农求职小助手");
}
}
public class SingleThreadExecutorTest {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
MyRunnable myRunnable = new MyRunnable();
for(int i = 0; i < 10; i++){
executorService.execute(myRunnable);
}
System.out.println("=======任务开始=======");
executorService.shutdown();
}
}
运行结果:
您点的“在看”就是对我最大的鼓励