Java 提供了三种创建线程的方法:
- 通过实现 Runnable 接口;
- 通过继承 Thread 类本身;
- 通过 Callable 和 Future 创建线程
1.通过继承 Thread 类本身; (单继承)
创建一个线程的第二种方法是创建一个新的类,该类继承 Thread 类,然后创建一个该类的实例。
继承类必须重写 run() 方法,该方法是新线程的入口点。它也必须调用 start() 方法才能执行。
该方法尽管被列为一种多线程实现方式,但是本质上也是实现了 Runnable 接口的一个实例。
package cn.qlu.thread;
/**
* 继承thread
* @author l
*
*/
public class TestThread extends Thread {
/**
* 线程入口
* @param args
*/
@Override
public void run() {
for(int i=0;i<20;i++){
System.out.println("啊啊啊啊啊");
}
}
public static void main(String[] args) {
//创建子类对象
TestThread t = new TestThread();
//启动线程 不保证立即运行,CPU调用
t.start();
for(int i=0;i<20;i++){
System.out.println("一边唱歌");
}
}
}
2.通过实现 Runnable 接口;(推荐使用)
创建一个线程,最简单的方法是创建一个实现 Runnable 接口的类。为了实现 Runnable,一个类只需要执行一个方法调用 run(),声明如下:public void run()
你可以重写该方法,重要的是理解的 run() 可以调用其他方法,使用其他类,并声明变量,就像主线程一样。在创建一个实现 Runnable 接口的类之后,你可以在类中实例化一个线程对象。
Thread 定义了几个构造方法,下面的这个是我们经常使用的:
Thread(Runnable threadOb,String threadName);
这里,threadOb 是一个实现 Runnable 接口的类的实例,并且 threadName 指定新线程的名字。
新线程创建之后,你调用它的 start() 方法它才会运行。void start();
package cn.qlu.thread;
/**
* 通过实现 Runnable 接口来创建线程
* @author l
*
*/
public class TestRunnable implements Runnable {
//重写run()方法
@Override
public void run() {
for(int i =0;i<20;i++){
System.out.println("一边唱歌");
}
}
public static void main(String[] args) {
new Thread(new TestRunnable()).start();
for(int i =0;i<20;i++){
System.out.println("一边dancing");
}
}
}
3.通过 Callable 和 Future 创建线程(并发领域)
可以throws 异常,并且Run() 是有返回值的
步骤:
-
1. 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
-
2. 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
-
3. 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
-
4. 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
package cn.qlu.thread;
/**
* Callable 可以Thread异常
* 用起来更强大但是麻烦
* 里面的call()带有返回值
*/
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CabllableDown implements Callable<Boolean>{
private String url; //远程路径
private String name; //存储名字
public CabllableDown(String url,String name){
this.url=url;
this.name=name;
}
@Override
public Boolean call() throws Exception {
WebDownloader w = new WebDownloader();
w.download(url, name);
System.out.println(name);
return true;
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
CabllableDown cd1 = new CabllableDown("https://pic2.zhimg.com/v2-7d01cab20858648cbf62333a7988e6d0_qhd.jpg","超人.jpg");
CabllableDown cd2 = new CabllableDown("http://tupian.baike.com/ipad/a0_16_12_01300535031999137270128786964_jpg","北京.jpg");
//创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(3);
//提交执行
Future<Boolean> result1 = ser.submit(cd1);
Future<Boolean> result2 = ser.submit(cd2);
//获取结果
boolean r1= result1.get();
boolean r2= result2.get();
//关闭服务
ser.shutdown();
}
}
以上仅用于个人学习,如有错误请指出!