JDK实现多线程编程的两种方式:实现Runnable接口和实现Callable接口

xiaoxiao2021-02-28  48

以面向接口的设计原则来说,实现多线程编程的方式有两种:实现Runnable接口;实现Callable接口。

实现Runnable接口

我们常见的两种实现多线程编程的方式:实现Runnable接口;继承Thread父类。Thread线程类是Runnable接口的实现类,java类不支持多根继承,类可以实现多个接口,且接口之间支持多根继承,因此此处推荐且只讨论以实现Runnable接口的方式实现多线程编程。

1.定义线程:实现接口Runnable,重写线程的入口方法:run()

public class MyRunnableThread implements Runnable{ public String taskName; public MyRunnableThread(String taskName) { super(); this.taskName = taskName; } @Override public void run() { System.out.println(taskName + " 被执行"); } }

2.运行线程:线程MyRunnableThread作为构造器参数构建线程运行类:Thread。Thread类的方法:start()启动线程。

public static void main(String[] args) { int threadSize = 5; for(int i = 0;i < threadSize;i++) { // Thread类的方法启动线程, new Thread(new MyRunnableThread("线程" + i)).start(); } } // 执行结果如下,可以看出线程执行的无序性 线程2 被执行 线程0 被执行 线程1 被执行 线程3 被执行 线程4 被执行

实现Callable接口

实现Callable接口和实现Runnable接口的线程不同之处就在于后者的线程有返回值,返回值被Future类封装,通过Future类的方法:get()可以获取线程的返回值。

1.定义线程:实现Callable接口,重写线程的入口方法:call()

public class MyCallableThread implements Callable<Object>{ private String taskName; public MyCallableThread(String taskName) { super(); this.taskName = taskName; } @Override public Object call() throws Exception { System.out.println(taskName + " 被执行"); return taskName; } }

2.推荐以线程池ExecutorService的方式运行MyCallableThread

public static void main(String[] args) throws InterruptedException, ExecutionException { int taskSize = 5; // 线程池的方式,执行带有返回值的线程(实现接口Callable):MyCallable // 线程池 ExecutorService executorService = Executors.newFixedThreadPool(taskSize); // 返回封装结果(Future<Object>)的集合 List<Future<Object>> futures = new ArrayList<>(taskSize); for(int i = 0;i < taskSize;i++) { futures.add(executorService.submit(new MyCallableThread("线程 :" + (i + 1)))); } // 关闭线程池 executorService.shutdown(); Thread.sleep(1000);// 暂停1秒 for (Future<Object> future : futures) { System.out.println(future.get()); } }
转载请注明原文地址: https://www.6miu.com/read-2627992.html

最新回复(0)