目录
一、继承Thread类(不推荐使用)
具体操作:
注意事项
二、实现Runnable接口(常用)
具体操作:
三、实现Callable接口(常用)
具体操作:
一、继承Thread类(不推荐使用)
继承Thread类,重写Run方法
具体操作:
- 定义一个子类MyThread继承线程类Thread,重写run()方法
- 创建MyThread类对象
- 调用线程对象的start()方法启动线程
public class Test {public static void main(String[] args) {MyThread t = new MyThread();t.start();}
}class MyThread extends Thread {public void run() {System.out.println(Thread.currentThread().getName());}
}
优点:编程简单
缺点:1、耦合度高,线程任务与线程对象绑定,一个线程任务只能由一个线程对象执行。
2、由于Java单继承特性,只能继承一个类,不能再继承其他类。
注意事项
1、启动线程调用的是start方法,而不是run方法
直接调用run方法会当成普通方法执行,相当于还是单线程
2、不要把主线程任务放在启动子线程之前
这样主线程会先结束,相当于单线程的效果
二、实现Runnable接口(常用)
实现Runnable接口,重写run()方法
具体操作:
- 定义一个线程任务类MyRunnable,实现Runnable接口,重写run()方法
- 创建MyRunnable任务对象
- 把MyRunnable任务对象交给Thread处理
public class Test2 {public static void main(String[] args) {//方式一MyRunnable runnable = new MyRunnable();Thread thread = new Thread(runnable);thread.start();//方式二:简化使用new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}}).start();}
}
class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}
}
优点:1、相同的任务可以由不同的线程执行,代码复用性提高。
2、更灵活,可以继承其他类
缺点:相比与继承Thread类,需要多创建Runnable线程任务对象
三、实现Callable接口(常用)
前两种创建方式都存在一个问题:不能返回执行结果!
具体操作:
- 定义一个类MyCallable实现Callable接口,重写call方法
- 创建MyCallable对象,封装成FutureTask
- 把线程任务对象交给Thread对象,调用start方法启动
- 线程执行完毕后,通过FutureTask对象的get方法获取执行结果
public class Test3 {public static void main(String[] args) throws ExecutionException, InterruptedException {//方式一MyCallable callable = new MyCallable();FutureTask<String> futureTask = new FutureTask<>(callable);Thread thread = new Thread(futureTask);thread.start();System.out.println(futureTask.get());}
}
class MyCallable implements Callable {@Overridepublic Object call() throws Exception {return Thread.currentThread().getName();}
}