一、前言
在前一篇博客中,小编向大家介绍了多线程的全局观,学习多线程的几个方向。在这篇博客中,小编会向大家介绍一下非常基础的线程的创建和启动。
二、线程创建的三种方式
- 继承Thread,重写run方法
- 实现Runable接口,重写run方法
- 使用Callable和Future创建线程
三、实现
接下来介绍创建线程的三种方式,当然,方式远不止这三种。
3.1 继承Thread类创建线程类
这是一种比较常见的一种方式,通过继承Thread类重写其中的run()方法。
栗如:
public class MyThread extends Thread {
String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println("当前执行线程的名字是:"+currentThread().getName());
}
public static void main(String[] args) {
//注意线程启动为start(),把线程置于就绪状态
new MyThread("Ares").start();
new MyThread("Sherry").start();
}
}
运行结果:
注:通过继承Thread类的方法来创建线程类的时,多个线程之间无法共享线程类的实例变量。
3.2 实现Runnable接口创建线程类
在创建Thread类时,可以指定一个Runnable参数,所以我们可以将Runnable接口的实现类传给Thread类,以实现线程。
public class MyRunableTest implements Runnable {
@Override
public void run() {
System.out.println("当前线程的名字是:"+Thread.currentThread().getName());
}
public static void main(String[] args) {
MyRunableTest myRunableTest = new MyRunableTest();
new Thread(myRunableTest,"Ares").start();
}
}
运行结果:
注:通过实现Runnable接口,线程间可以共享Runnable实现类的实例变量。
3.3 使用Callable和Future创建线程
java5开始提供了一个Callable接口,Callable接口提供了一个call()方法作为线程的执行体。call()方法比传统的run()方法功能更强大,call()方法运行有返回值,允许抛出异常。
java5提供了Future接口作为Callable接口里call()方法的返回值,Future实现类提供了FutureTask实现类,FutureTask不仅仅实现了Future接口,还实现了Runnable接口。该类可以作为线程的target使用。
public class MyCallableTest implements Callable {
@Override
public Object call() throws Exception {
System.out.println("当前执行的线程名称为:"+Thread.currentThread().getName());
return true;
}
public static void main(String[] args) {
//创建Callable对象
MyCallableTest myCallableTest = new MyCallableTest();
//创建一个FutureTask任务
FutureTask<Boolean> task=new FutureTask<Boolean>(myCallableTest);
//启动线程
new Thread(task,"Ares").start();
//获取线程的返回值
try {
System.out.println("线程执行返回的结果为:"+task.get());//一直阻塞,直到返回值
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("执行完毕");
}
}
运行结果:
这里说明一下FutureTask类,它实现了RunnableFuture接口,而RunnableFuture接口实现了Runnable接口。这样,Thread的构造方法就可以使用了。
下面是Thread的构造方法:
包含了:
- 构造 Runnable实例
- 构造 Runnable实例 + 名字
- 构造线程组,Runnable实例
- 线程名字
- 等等
四、小结
通过这次的亲自动手操作算是对代码有了一定的了解,对线程创建和启动有了一定的认识,下一节会对线程的生命周期进行分析,这样大家就可以针对生命周期并且结合代码,更好的认识代码运行的过程。