1.继承于Thread类,重写run()方法;
2.实现Runable接口,实现里面的run()方法;
前两种不用多说
3.使用 FutureTask 实现有返回结果的线程,可以返回线程执行结果
public class Test {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask<Double> task = new FutureTask(new MyCallable());
//创建一个线程,异步计算结果
Thread thread = new Thread(task);
thread.start();
//主线程继续工作
Thread.sleep(1000);
System.out.println("主线程等待计算结果...");
//当需要用到异步计算的结果时,阻塞获取这个结果
Double d = task.get();
System.out.println("计算结果是:"+d);
//用同一个 FutureTask 再起一个线程
Thread thread2 = new Thread(task);
thread2.start();
}
}
class MyCallable implements Callable<Double>{
@Override
public Double call() {
double d = 0;
try {
System.out.println("异步计算开始.......");
d = Math.random()*10;
d += 1000;
Thread.sleep(2000);
System.out.println("异步计算结束.......");
} catch (InterruptedException e) {
e.printStackTrace();
}
return d;
}
}
4.使用ExecutorService、Executors 线程池。
public class MyTest {
public static void main(String[] args) {
//创建一个只有一个线程的线程池
ExecutorService executorService = Executors.newFixedThreadPool(3);
//创建任务,并提交任务到线程池中
executorService.execute(new MyRunable("任务1"));
executorService.execute(new MyRunable("任务2"));
executorService.execute(new MyRunable("任务3"));
}
}
class MyRunable implements Runnable{
private String taskName;
public MyRunable(String taskName) {
this.taskName = taskName;
}
@Override
public void run() {
System.out.println("线程池完成任务:"+Thread.currentThread().getName()+taskName);
}
}
二、关于run()方法的思考
看看下面这种情况:线程类Thread 接收了外部任务,同时又用匿名内部类的方式重写了内部的run()方法,这样岂不是有两个任务,那么究竟会执行那个任务呢?还是两个任务一起执行呢?
public class TestNeibu{
public static void main(String[] args) {
Thread thread = new Thread(new MyTask()){
@Override
public void run() {//重写Thread类的run方法
System.out.println("Thread 类的run方法");
}
};
//线程启动
thread.start();
}
}
class MyTask implements Runnable{
//重写run方法
@Override
public void run() {
//任务内容....
System.out.println("这是Runnable的run方法");
}
}
运行结果如下:
Thread 类的run方法
Thread类的run方法在没有重写的情况下,是判断一下是否有Runnable 对象传进来,如果有,那么就调用Runnable 对象里的run方法;否则,就什么都不干,线程结束。所以,针对上面的例子,一旦你继承重写了Thread类的run()方法,而你又想可以接收Runable类的对象,那么就要加上super.run(),执行没有重写时的run方法,改造如下
Thread thread = new Thread(new MyTask()){
@Override
public void run() {//重写Thread类的run方法
//调用父类Thread的run方法,即没有重写时的run方法
super.run();
System.out.println("Thread 类的run方法");
}
};
thread.start();