java中创建线程的四种方法以及区别
Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。Java可以用四种方式来创建线程,如下所示:
1、继承Thread类创建线程
先看下Thread的源码
public class Thread implements Runnable{
private Runnable target;
public Thread(Runnable target) {
this.target = target;
......
}
public void run() {//重写Runnable的run方法
if (target != null) {
target.run();
}
}
}
Thread也是实现了Runnable方法并重写了run的方法
代码实例
public class MyThread extends Thread{//继承Thread类
//重写run方法
public void run(){
//业务逻辑
}
}
new MyThread().start();//创建并启动线程
2、Runnable+Thread
通过实现Runnable接口创建任务,并使用Thread创建线程并启动:
代码实例:
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
new Thread(myRunnable).start();//创建线程并启动任务
}
class MyRunnable implements Runnable{
@Override
public void run() {
//业务代码
}
}
3、使用Future创建异步任务
和Runnable接口不一样,Callable接口提供了一个call()方法作为线程执行体,call()方法比run()方法功能要强大。
- call()方法可以有返回值
- call()方法可以声明抛出异常
Java5提供了Future接口来代表Callable接口里call()方法的返回值,并且为Future接口提供了一个实现类FutureTask,这个实现类既实现了Future接口,还实现了Runnable接口,因此可以作为Thread类的target。在Future接口里定义了几个公共方法来控制它关联的Callable任务。
boolean cancel(boolean mayInterruptIfRunning):
视图取消该Future里面关联的Callable任务
V get():返回Callable里call()
方法的返回值,调用这个方法会导致程序阻塞,必须等到子线程结束后才会得到返回值
V get(long timeout,TimeUnit unit):
返回Callable里call()方法的返回值,最多阻塞timeout时间,经过指定时间没有返回抛出TimeoutException
boolean isDone():若Callable任务完成,返回True
boolean isCancelled():如果在Callable任务正常完成前被取消,返回True
3.1、使用Callable+FutureTask+Thread
public static class MyCallable implements Callable {
@Override
public Object call() throws Exception {
return 4;
}
}
public static void main(String[] args) {
MyCallable th = new MyCallable();//创建Callable
//创建FutureTask,需要绑定Callable
FutureTask<Integer> futureTask = new FutureTask<Integer>(th);
new Thread(futureTask).start();
Integer result = futureTask.get();//获取Callable的返回值
}
3.2、使用Runnable+FutureTask+Thread
public static class MyRunnable implements Runnable {
@Override
public void run() {
//业务代码
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyRunnable runnable = new MyRunnable();//创建Runnable
Integer result = null;
FutureTask<Integer> futureTask = new FutureTask<Integer>(runnable,result);//创建FutureTask,需要绑定Runnable
new Thread(futureTask).start();
}
4、使用线程池Executor
注意:严格意义上来说只有一种,都是创建Thread对象来创建线程。
原文链接:https://blog.csdn.net/m0_37840000/article/details/79756932