Java 创建线程的3种方法及各自的优点
1.继承Thread类,然后调用start方法。
classMyThreadextendsThread{
//重写run方法,线程运行后,跑的就是run方法
publicvoidrun(){
//System.out.println("");
}
publicstaticvoidmain(String[]args){
Threadt1=newMyThread();
t1.start();//线程运行,调用的run()方法.
}
}
2.实现Runnable接口的run方法,然后再用Thread类包裹后,调用start方法。
classTestThreadimplementsRunnable{
@Override
publicvoidrun(){
//implementrunmethodhere
//System.out.println("");
}
publicstaticvoidmain(){
finalTestThreadobj=newTestThread();
Threadt1=newThread(obj);
t1.start();
}
}
3.实现Callable接口的call方法,用FutureTask类包裹Callable对象。然后再用Thread类包裹FutureTask类,并调用start方法。call()方法可以有返回值。
classMyCallableimplementsCallable{
@Override
publicIntegercall()throwsException{
intsum=0;
for(inti=1;i<=100;i++){
sum+=i;
}
returnsum;
}
publicstaticvoidmain(String[]args)throwsException{
MyCallablemc=newMyCallable();//实例化callable
FutureTaskoneTask=newFutureTask(mc);//用FutureTask包裹
ThreadoneThread=newThread(oneTask);//用Thread包裹
oneThread.start();
System.out.print(oneTask.get());//获取返回值
}
}
Callable方法在Java8后,支持拉姆达表达式的写法,可以创建一个FutureTask类,语句上不是太罗嗦。Callable方式有以下几个优点:
- 可以捕获线程上的异常。
- 可以通过get方法得到返回值。
- get方法阻塞当前线程,直到调用的线程运行结束。
- 可以取消线程的运行。
下面代码演示了使用FutureTask类运行线程,捕获异常的例子:
FutureTasktask=newFutureTask (()->{ thrownewException("自定义异常"); }); newThread(task).start(); try{ System.out.println(task.get()); }catch(Exceptione){ System.out.println(e.getMessage()); }
Java6之后,还可以通过创建线程池来创建线程,使用ExecutorService的execute方法:
ExecutorServicees=Executors.newCachedThreadPool(); Runnabler=; es.execute(r);
实现Runnable接口相对于继承Thread类的优势:
(1)适合多个相同程序代码的线程去处理同一资源的情况
(2)可以避免由于java单一继承带来的局限性
(3)用接口的方式将你的代码和线程实现分离,更加清晰。
(4)通过继承Thread类,每个线程都有一个相关联的唯一对象,而实现Runnable接口,多线程可以共享同一个Runnable实例。
(5)增强了程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。
以上就是Java创建线程的3种方法及各自的优点的详细内容,更多关于JAVA创建线程的资料请关注毛票票其它相关文章!