【多线程 - 02、创建线程】

Java 使用 Thread 类代表线程,所有的线程对象都必须是 Thread 类或其子类的实例

一、继承 Thread 类

1、步骤

a. 定义 Thread 类的子类,并重写该类的 run() 方法,该 run() 方法的方法体就代表了线程需要完成的任务,因此经常把 run() 方法称为线程执行体

b. 创建 Thread 子类的实例,即创建了线程对象

c. 调用线程对象的 start() 方法启动该线程

2、编程

public class ThreadTest {
    public static void main(String[] args) {
        for (int i = 1;i<15;i++){//主线程名:main
            System.out.println("线程名字:"+Thread.currentThread().getName()+"-"+i);
            if (i == 5){
                //start方法通知线程可以启动运行
                new Test().start();//线程名字:Thread-0
                new Test().start();//线程名字:Thread-1
            }
        }
    }
}
class Test extends Thread{
    @Override
    public void run() {
        super.run();
        for (int i = 1;i<=10;i++){
            System.out.println("线程名字:"+this.getName()+"-"+i);
        }
    }
}
//结果会出现主线程和两个子线程交错打印出结果

二、实现 Runnable 接口

1、步骤

a. 定义 Runnable 接口的实现类,并重写该接口的 run() 方法

b. 创建 Runnable 实现类的实例,并将此实例作为形参传入 new Thread() 的构造函数中,就可创建 Thread 线程对象

c. 调用线程对象的 start() 方法启动该线程

public class ThreadTest {
    public static void main(String[] args) {
        for (int i = 1;i<15;i++){//主线程名:main
            System.out.println("线程名字:"+Thread.currentThread().getName()+"-"+i);
            if (i == 5){
                //start方法通知线程可以启动运行
                //也可以使用匿名内部类实现
                new Thread(new Test(),"线程名1").start();
                new Thread(new Test(),"线程名2").start();
            }
        }
    }
}
class Test implements Runnable{
    @Override
    public void run() {
        for (int i = 1;i<=10;i++){
            System.out.println("线程名字:"+Thread.currentThread().getName()+"-"+i);
        }
    }
}
//结果会出现主线程和两个子线程交错打印出结果

三、实现 Callable 接口

1、步骤

a. 创建 Callable 接口的实现类,重写 call() 方法 ,该方法就是线程方法执行体,call() 方法有返回值

b. 创建 Callable 实现类的实例

c. 使用 FutureTask 类的实例,来包装 Callable 对象,即把 callable 的实例以形参的方式传入 new FutureTask() 的构造函数中

d. 使用 FutureTask 对象作为 Thread 对象的 target 创建启动线程

e. 调用线程对象的 start() 方法启动该线程

f. 通过 FutureTask 实例对象调用 get() 方法得到子线程的返回值

2、编程

public class ThreadTest {
    public static void main(String[] args) {
        Test test = new Test();
        FutureTask<Double> task1 = new FutureTask(test);
        FutureTask<Double> task2 = new FutureTask(test);

        for (int i = 1;i<15;i++){//主线程名:main
            System.out.println("线程名字:"+Thread.currentThread().getName()+"-"+i);
            if (i == 5){
                //start方法通知线程可以启动运行
                new Thread(task1,"线程名1").start();
                new Thread(task2,"线程名2").start();
            }
        }
        try {
            Double rs1 = task1.get();//返回值会等子线程运行完后获得
            Double rs2 = task2.get();
            System.out.println(rs1+"-----"+rs2);

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
class Test implements Callable {
    @Override
    public Object call() throws Exception {
        for (int i = 1;i<15;i++){
            System.out.println("线程名字:"+Thread.currentThread().getName()+"-"+i);
        }
        return Math.random();
    }
}
//结果会出现主线程和两个子线程交错打印出结果

四、创建线程的三种方式对比

使用实现 Runnable 、Callable 接口的方式创建多线程

优点:

  • 线程类只是实现了 Runnable 接口或 Callable 接口,同时还可以继承其他类
  • 多个线程可以共享一个 target 对象,非常适合多个相同线程来处理同一份资源的情况

缺点:

  • 编程稍微复杂,如果需要访问当前线程,必须使用 Thread.currentThread() 方法

使用继承Thread类的方式创建多线程

优点:

  • 编写简单,如果要访问当前线程,无需使用 Thread.currentThread() 方法,可以直接使用 this 的方式获取当前线程

缺点:

  • 不能再继承其他类

项目中推荐使用 Runnable 接口或 Callable 接口创建多线程

  • 21
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玄天灵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值