Java中有哪几种方式来创建线程执行任务?

1、继承Thread类

你可以创建一个继承自Thread类的子类,并重写run()方法来定义线程的任务。然后,通过创建子类的对象并调用start()方法来启动线程。

class MyThread extends Thread {
    public void run() {
        // 线程任务代码
    }
}

MyThread thread = new MyThread();
thread.start();

总结:重写的是run方法,而不是start方法,但是占用了继承的名额,java中是单继承

2、实现Runnable接口

你可以创建一个实现了Runnable接口的类,实现run()方法来定义线程的任务。然后,将Runnable对象传递给一个Thread对象并启动它。

class MyRunnable implements Runnable {
    public void run() {
        // 线程任务代码
    }
}

MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();

总结:使用Runnable接口,实现run()方法,使用依然要用到Thread,这种方式更常用

还可以使用匿名内部类和Lambda表达式

public class Thread01 {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            public void run() {
                //要执行的代码
            }
        });
        thread.start();
    }
}
public class Thread01 {
    public static void main(String[] args) {
        //1.第一种
        Thread thread = new Thread(()-> System.out.println("要执行的代码"));
        //2.第二种
        Runnable runs = ()->{
            System.out.println("要执行的代码");
        };
        Thread thread2 = new Thread(runs);
        thread.start();
        thread2.start();
    }
}

3、使用Executor框架

Java提供了java.util.concurrent包,其中包括Executor框架,它允许你更灵活地管理和执行线程。你可以使用ExecutorService接口创建线程池,并将任务提交给线程池执行。

ExecutorService executor = Executors.newFixedThreadPool(5); // 创建一个固定大小的线程池
executor.execute(new Runnable() {
    public void run() {
        // 线程任务代码
    }
});
executor.shutdown(); // 关闭线程池

总结:实现Callable接口或者Runnable接口都可以,由ExecutorService管理线程池

 4、使用Callable和Future

 与Runnable不同,Callable允许线程返回结果。你可以使用Callable接口和Future对象来执行任务并获得任务的结果。

Callable<Integer> task = new Callable<Integer>() {
    public Integer call() throws Exception {
        // 线程任务代码
        return 42;
    }
};

ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(task);
Integer result = future.get(); // 获取任务结果
executor.shutdown();

 使用Callable和FutureTask

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CallableFutureTaskExample {
    public static void main(String[] args) {
        // 创建一个Callable任务
        Callable<Integer> callable = new MyCallable();

        // 使用FutureTask包装Callable任务
        FutureTask<Integer> futureTask = new FutureTask<>(callable);

        // 创建一个线程来执行FutureTask
        Thread thread = new Thread(futureTask);
        thread.start();

        try {
            // 获取任务的结果,该方法会阻塞直到任务完成
            Integer result = futureTask.get();
            System.out.println("Task result: " + result);
        } catch (InterruptedException | ExecutionException e) {
            // 处理异常
            e.printStackTrace();
        }
    }
}

在这个示例中,我们首先创建了一个Callable任务(MyCallable类),然后使用FutureTask来包装这个任务。接下来,我们创建一个线程来执行FutureTask,然后通过get()方法来等待任务完成并获取结果。get()方法可能会抛出InterruptedExceptionExecutionException异常,需要进行适当的异常处理。

使用CallableFutureTask的主要优点是可以更灵活地处理任务的结果,也可以在需要时取消任务的执行。此外,FutureTask还提供了一些其他方法,允许你查询任务的状态和取消任务的执行。这对于处理复杂的多线程场景非常有用。

 

posted @ 2023-09-19 09:48  CYF0913  阅读(159)  评论(0)    收藏  举报