Java多线程实现的三种方式
- 继承Thread类,然后覆写run方法;
- 实现Runnable接口,而后覆写run方法;
- 实现Callable接口,而后覆写
call<V>
方法。
1. 继承Thread类
java.lang.Thread
是一个线程的操作核心类。新建一个线程最简单的方法就是直接继承Thread类,然后覆写该类中的run()方法。
举例:继承Thread类
class MyThread extends Thread{
@Override
public void run() {
System.out.println("直接继承Thread类");
}
}
public class Test {
public static void main(String[] args) {
Thread t1 = new MyThread();
t1.start(); //start方法启动线程,最后调用的还是run方法
}
}
2. Runnable接口实现多线程
举例:用Runnable实现
class MyThread implements Runnable{
@Override
public void run() {
System.out.println("实现Runnable接口");
}
}
public class Test {
public static void main(String[] args) {
Runnable r = new MyThread();
Thread t1 = new Thread(r);
t1.start();
}
}
因为启动线程用的是start方法,而只有Thread类中有该方法,那就要Thread类和Runnable接口相关联,刚好Thread类中提供了一个构造方法,如下:
public Thread(Runnable target)
另外,查看Thread类中run方法:
上面中的target
就是Runnable对象,上面例子中的r
.
3. 实现Callable接口
该接口特点:线程任务执行后有返回值。
要用Callable实现多线程,就要和Thread类相关联。如下图:
由上图可知,最主要的类就是FutureTask
类,该类是Runnable的子类,又和Callable接口关联。FutureTask中有该方法:
public FutureTask(Callable<V> callable)
查看FutureTask中的run方法源码:
其中调用的就是Callable中的call方法。
举例:实现Callable接口
class MyThread1 implements Callable<String> {
private int ticket = 10;
@Override
public String call() {
while(ticket > 0 ){
System.out.println(Thread.currentThread().getName()+" 剩余票数:"+ticket--);
}
return "票卖完了";
}
}
public class Test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable callable = new MyThread1();
FutureTask<String> futureTask = new FutureTask<>(callable);
Thread t1= new Thread(futureTask);
t1.start();
//获取返回值
System.out.println(futureTask.get());
}
}
总结:继承Thread和实现Runnable区别?
- 继承Thread类有单继承局限,相对而言Runnable接口更加灵活;
- 实现Runnable接口可以更好的实现程序共享的概念。