1、继承Thread类
优点: 编码简单
缺点: 无法继承其他类了,不利于扩展
资源共享: 不能资源共享
1.1 实现步骤
1、定义Thread类的子类,重写run方法;
2、创建Thread子类的实例;
3、调用该实例的start方法启动线程。
1.2 代码演示
public class Thread_01 extends Thread {
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println("工作线程---" + i + "----" + Thread.currentThread().getName());
}
}
}
// 创建Thread_02 线程
public class Thread_02 extends Thread{
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println("听歌线程---"+i+"----"+Thread.currentThread().getName());
}
}
}
//测试
public static void main(String[] args) {
//创建线程对象
Thread_01 thread_01 = new Thread_01();
Thread_02 thread_02 = new Thread_02();
//启动线程
thread_01.start();
thread_02.start();
}
//测试结果
听歌线程---0----Thread-1
工作线程---0----Thread-0
听歌线程---1----Thread-1
工作线程---1----Thread-0
听歌线程---2----Thread-1
工作线程---2----Thread-0
2、实现Runnable接口
优点: 线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。
缺点: 编程多一层对象包装,如果线程有执行结果不可以直接返回。
资源共享: 能资源共享 。
2.1 实现步骤
1、定义类实现Runnable接口;
2、重写run()方法;
3、main方法中实例化Runnable接口的实现类对象;
4、定义两个线程Thread类的对象,把Runnable接口的实现对象传入构造方法中;
5、线程类对象调用start方法,启动线程,自动执行。
2.2 代码演示
public class RunnableTest1 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println("听歌线程---"+i+"----"+Thread.currentThread().getName());
}
}
}
public class RunnableTest2 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println("工作线程---"+i+"----"+Thread.currentThread().getName());
}
}
}
//测试
public static void main(String[] args) {
//创建runnable接口的实现类对象
RunnableTest1 runnableTest1 = new RunnableTest1();
RunnableTest2 runnableTest2 = new RunnableTest2();
//创建线程对象,通过线程对象来开启我们的线程,代理
new Thread(runnableTest1).start();
new Thread(runnableTest2).start();
}
//测试结果
工作线程---0----Thread-1
听歌线程---0----Thread-0
听歌线程---1----Thread-0
听歌线程---2----Thread-0
工作线程---1----Thread-1
工作线程---2----Thread-1
3、实现Callable接口
优点: 线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强,在这种方式下,多个线程可以共享一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
缺点: 编程稍稍复杂,如果需要访问当前线程,则必须使用Thread.currentThread() 方法。
资源共享: 能资源共享,适用于异步编程。
3.1 实现步骤
1、定义Callable接口的实现类,并重写call方法;
2、创建Callable实现类的对象,使用FutureTask包装该对象,并以此为target创建线程对象;
3、调用线程对象的start方法启动该线程对象;
4、通过FutureTask包装对象获取返回值。
3.2 代码演示
public class CallableTest1 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int num = new Random().nextInt(100);
System.out.println("工作线程---"+Thread.currentThread().getName()+" 随机数:"+num);
return num;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//1.创建Callable的实现内对象
CallableTest1 callableTest1 = new CallableTest1();
//2.使用FutureTask接收Callable对象
FutureTask<Integer> futureTask = new FutureTask<>(callableTest1);
//3.创建线程,并开启线程
new Thread(futureTask).start();
//4.获取Callable返回值 futureTask.get()
Integer integer = futureTask.get();
System.out.println("integer = " + integer);
}
}
//测试结果
工作线程---Thread-0 随机数:52
integer = 52