创建线程方式
继承 Thread 类
java
public class ThreadExtendTest {
public static class MyThread extends Thread {
@Override
public void run() {
System.out.println("I'm child thread name is" + this.getName());
}
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
}
}
- MyThread 类继承 Thread 类, 重写了 run()方法。main 函数创建 MyThread 实例,调用改实例的 start 方法启动线程。
- 当创建完 thread 对象后该线程并没有被启动执行,直到调用了 start 方法后才真正启动了线程。其实调用 start 方法后线程并没有马上执行而是处于就绪状态, 这个就绪状态是指该线程已经获取了除 CPU 资源外的其他资源,等待获取 CPU 资源后才会真正处于运行状态
- 一旦 run 方法执行完毕,该线程就处于终止状态
- 在 run() 方法内获取当前线程直接使用 this 就可以了,无须使用 Thread. currentThread() 方法;
- 不好的地方是 Java 不支持多继承,如果继承了 Thread 类,那么就不能再继承其他类。另外任务与代码没有分离, 当多个线程执行一样的任务时需要多份任务代码,而 Runable 则没有这个限制。
实现 Runnable 接口
java
public class ThreadImplRunnableTest {
public static class RunnableImpl implements Runnable {
@Override
public void run() {
System.out.println("RunnableImpl.run on " + Thread.currentThread().getName());
}
}
public static void main(String[] args) {
RunnableImpl runnableImpl = new RunnableImpl();
Thread thread = new Thread(runnableImpl);
thread.start();
Thread thread1 = new Thread(runnableImpl);
thread1.start();
}
}
- 两个线程共用一个 task 代码逻辑,如果需要,可以给 RunableTask 添加参数进行任务区分。另外, RunableTask 可以继承其他类。但是上面介绍的两种方式都有一个缺点,就是任务没有返回值
FutureTsk
java
public class CallableTaskTest {
public static class CallableTask implements Callable<String> {
@Override
public String call() throws Exception {
return " executor task job";
}
}
public static void main(String[] args) throws Exception {
FutureTask task = new FutureTask<>(new CallableTask());
new Thread(task).start();
String result = (String) task.get();
System.out.println(result);
}
}
- CallerTask 类实现了 Callable 接口的 call()方法。在 main 函数内首先创建了一个 FutrueTask 对象(构造函数为 CallerTask 的实例),然后使用创建的 FutrueTask 对象作为任务创建了一个线程并且启动它,最后通过 futureTask.get() 等待任务执行完毕并返回结果。
使用线程池方式
java
public class ThreadPoolThreadTest {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);//创建一个固定大小的线程池
for (int i = 0; i < 10; i++) {
int taskId = i;
executor.execute(()->{
System.out.println("Executing task "+ taskId);
});
}
executor.shutdown();//关闭线程池
}
}