商城网站建设怎么收费,做网站优化哪家公司好,互联网行业怎么样,建站网站哪个最好Java创建并执行线程的四种方法
java里面创建线程有四种方式#xff1a; 无返回#xff1a;
实现Runnable接口#xff0c;重写run();继承Thread类#xff0c;重写run(); 有返回#xff1a;实现Callable接口#xff0c;重写call(),利用FutureTask包装Callable#xff0c…Java创建并执行线程的四种方法
java里面创建线程有四种方式 无返回
实现Runnable接口重写run();继承Thread类重写run(); 有返回实现Callable接口重写call(),利用FutureTask包装Callable并作为task传入Thread构造函数利用线程池
下面来看看具体的创建方式 5. 继承Thread类重写run() 创建创建线程只需要继承Thread类然后在run方法里写下线程要实现的任务即可 调用通过调用start方法来启动线程而不能直接调用run方法。
① Thread类本质上是实现了Runnable接口Thread对象代表一个线程的实例。 ② Runnable接口只有一个抽象的run()方法。 ③ 启动线程的唯一方法就是通过Thread类的start()实例方法。 ④ start()方法是一个native方法它将启动一个新线程并执行run()方法。 ⑤ 自定义类直接extend Thread并复写run()方法就可以启动新线程并执行自己定义的run()方法。 6. 创建任务实现Runnable接口,重写run()。受欢迎 因为Java只能单继承继承了Thread类就不能再继承别的类了所以实现继承更推崇的是让线程类实现Runnable接口。 将Runnbale作为参数传入Thread的构造函数创建Thread. 3. Callable接口只包含抽象方法V call()。 利用Callable接口创建并启动新线程的步骤 ① 定义MyClass实现Callable接口Class MyClass implements Callable ② 重写call(),将执行的代码写入 ③ 创建FutureTask的对象FutureTask中定义了run(),run()内部调用了call(),并保存了call()的返回值FutureTask futuretask new FutureTask(newMyClass()); ④ 创建Thread的对象Thread thread new Thread(futuretask);//传入参数Runnable接口 ⑤ 启动线程;thread.start();[图片] ⑥ 可通过FutureTask类的get()方法获得线程执行结束后的返回值即call的返回值。futuretask.get();
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class MyThread {public static void main(String[] args) throws InterruptedException {FutureTaskInteger task new FutureTaskInteger(new CallableImpl());Thread thread new Thread(task);thread.start();try {System.out.println(task.get() returns task.get());} catch (ExecutionException e) {e.printStackTrace();}}
}class CallableImpl implements CallableInteger {private static Integer value 0;Overridepublic Integer call() throws Exception {System.out.println(执行call方法之前 value value);value value.intValue() 1;System.out.println(执行call方法之后 value value);return value;}
}运行结果 执行call方法之前 value 0 执行call方法之后 value 1 task.get() returns 1 4. 通过线程池来创建线程 ① new ThreadPoolExecutor(…); ② 创建任务Task implements Callable重写run()方法 ③ 通过线程池的execute()或submit()将任务command传入线程池; ④ 获取返回值
实现Callable接口重写call()方法 class CallableImpl implements Callable定义线程池 ThreadPoolExecutor executor利用submit()方法提交任务 Future future executor.submit(new CallableImpl());利用FutureTask类get()方法获取返回值 res task.get(); 这里future申明为Future对象但是它是由FutureTask实现的也可以直接申明为FutureTask future:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class MyThreadPool {public static void main(String[] args) throws InterruptedException, ExecutionException {ThreadPoolExecutor executor new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,new ArrayBlockingQueueRunnable(20));Future task;for (int i 0; i 5; i) {task executor.submit(new CallableImpl());System.out.println(线程返回结果 task.get());}executor.shutdown();}
}class RunnableImpl implements Runnable {Overridepublic void run() {// TODO Auto-generated method stubSystem.out.println(hhh);System.out.println(Thread.currentThread().getName());}
}运行结果 执行call方法之前 value 0 执行call方法之后 value 1 线程返回结果1 执行call方法之前 value 1 执行call方法之后 value 2 线程返回结果2 执行call方法之前 value 2 执行call方法之后 value 3 线程返回结果3 执行call方法之前 value 3 执行call方法之后 value 4 线程返回结果4 执行call方法之前 value 4 执行call方法之后 value 5 线程返回结果5
总结 线程的创建有四种方式主要分为有返回和无返回具体根据使用场景来选择。
如果不需要返回且线程数量小则建议采用实现Runnable接口重写run()的方式如果需要返回且线程数量小则建议采用实现Callable接口重写call()利用FutureTask包装成一个Runnable再作为参数传入Thread的构造方法的方式创建线程如果线程数量较多则建议采用线程池方式创建execute提交任务实现无返回操作submit提交任务实现有返回操作。
补充FutureTask JDK1.8中FutureTask实现了RunnableFuture而RunnableFuture顾名思义就是Runnable接口和Future接口的结合体。因此FutureTask对象可以作为Runnable对象来用比如 Thread thread new Thread(new FutureTaskV());也可以作为Future来用。这就是Java的有魅力的地方。。。 public class FutureTaskV implements RunnableFutureVpublic interface RunnableFutureV extends Runnable, FutureV {void run();}