实现多线程有三种方式. 如果想要在java中实现多线程主要使用两种途径.
- 继承Therad类(java.lang.Object.java.lang.Thread)
- 实现Runnable接口(Cloneable(在java.lang包下))
- Callable接口java.util包下;
1.Thread类是一个支持多线程的功能类,只要有一个子类就可以实现多线程的支持.所有线程的都有自己的起点run();方法.
在线程的每个主体类之中都必须覆写Thread类中所提供的run();线程操作主类.
public void run(){};表示线程一旦开始就要一直执行下去没有返回值.
启动多线程的唯一方法是 使用public void start(){};方法
使用run();方法并不能启动多线程.
public synchronized void start() {
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
}
}
}
private native void start0();
△Thread 类的start()方法不仅仅要启动多线程的执行代码,还要根据不同的操作系统进行资源的分配.
2.第二种实现方式实现Runnable接口
Thread 类可以实现多线程的主体类定义,但是java具有单继承局限针对类的继承都应该回避的问题,解决单继承局限
为了解决单继承的局限,在Java里面专门提供了Runnable接口.
@FunctionalInterface(函数式接口)
public interface Runnable
函数式接口的最大特征是只能定义一个方法,做方法引用使用.
接口里的方法都是public定义的.写不写都是public定义的权限.
两种方式的区别,继承Thread类可以直接使用start();方法.如果实现Runnable接口.并没有start()方法可以被继承.
不过何时启动多线程都需要使用Thread类完成,在Thread类中定义有以下构造方法
-
public Thread(Runnable target);接受Runnable接口对象;由此避免了单继承局限.
- 在日常开发工作中使用实现Runnable接口是最为合适的.
多线程两种实现方式的区别:
使用实现Runnable接口比继承Thread类,解决了java单继承局限.如果使用一定使用Runnable接口
public class Thread extends Object implements Runnable
Thread类实现了Runnable接口
使用Runnnable 类
1.客户端调用start()方法调用Thread类,Thread 类
- 操作系统的资源分配
- 调用run(核心功能)
- 类似于代理设计模式
- Thread类调用线程操作类,线程操作类主要实现多线程的核心功能.
- 使用Runnable 接口可以比Thread 类更好的描述出数据共享这一概念多个线程访问同一资源的操作.
此时也是三个对象,但同时占着线程操作类的对象引用也就是三个线程访问同一数据资源,
面试题:Thread类和Runnable接口实现多线程的区别.or 解释多线程两种实现方式的区别?
- Thread类是Runnable接口的之类,使用Runnable接口可以解决Thread类的单继承局限,
- Runnable 接口比Thread类实现多线程更好的描述数据共享这一概念.
3.第三种方式实现多线程
- 出现的原因
虽然Runnable 接口比Thread 类更好的解决了单继承局限性和实现了数据共享的概念.但是线程主方法run();不能返回操作结果 为了解决这问题从而出现了第三种方式,Callable接口.实现相对复杂一些.
- java.util.concurrent.Callable<V>
- 由于Thread类没有接收Callable接口的方法应用因此无法直接启动.
- 从jdk1.5开始提供了这个样一个类
java.util.concurrent.FutureTask<V> //定义结构 public class FutureTask<V> extends Object implements RunnableFuture<V>
所实现的RunnableFuture<v>主要负责Callable接口操作的,下图定义结构
-
public interface RunnableFuture<V> extends Runnable, Future<V> //FutureTask构造方法 public FutureTask(Callable<V> callable) public FutureTask(Runnable runnable, V result)
接收Runnable 接口的目的只有一个处理call();方法的返回结果.由于RunnableFuture继承Runnable接口是其子类所以可以接收RunnableFuture接口对象,接受返回值信息比较麻烦,向Thread类进行靠拢