创建线程的几种方式

创建线程的几种方式


一、继承 Thread 类

通过继承 Thread 类,并重写它的 run 方法,我们就可以创建一个线程。

  • 首先定义一个类来继承 Thread 类,重写 run 方法。
  • 然后创建这个自定义类的对象,并调用 start 方法启动线程。

 /**
 * 多线程实现的第一种方法,继承Thread 
 *
 */

//1.自定义一个类,继承java.lang包下的Thread类
class MyThread extends Thread {
    //2.重写run方法
    public void run() {		
        //3.将要在线程中执行的代码编写在run方法中
        for(int i = 0; i < 1000; i++) {		
            System.out.println("monkey");
        }
    }
}

public class ThreadTest01 extends Thread {

    public static void main(String[] args) {
        //4.创建上面自定义类的对象
        //创建一个线程
        MyThread mt = new MyThread();		
        
        //5.调用start方法启动线程
        mt.start();							
        
        //将循环的次数设置多一些,否则还没等到CPU切换就已经打印完成了
        for(int i = 0; i < 1000; i++) {
            System.out.println("1024");
        }
    }

}

二、实现 Runnable 接口

通过实现 Runnable ,并实现 run 方法,也可以创建一个线程。

  • 首先定义一个类实现 Runnable 接口,并实现 run 方法。
  • 然后创建 Runnable 实现类对象,并把它作为 target 传入 Thread 的构造函数中
  • 最后调用 start 方法启动线程。
 /**
 * 多线程实现的第二种方法,实现Runnable接口
 *
 */

// 1.自定义一个类实现java.lang包下的Runnable接口
class MyRunnable implements Runnable {

    // 2.重写run方法
    @Override
    public void run() {
        // 3.将要在线程中执行的代码编写在run方法中
        for (int i = 0; i < 1000; i++) {
            System.out.println("monkey");
        }
    }

}

public class ThreadTest02 {

    public static void main(String[] args) {
        // 4.创建上面自定义类的对象
        MyRunnable mr = new MyRunnable();

        // 5.创建Thread对象并将上面自定义类的对象作为参数传递给Thread的构造方法
        Thread t = new Thread(mr); 

        //6.调用start方法启动线程
        t.start();

        for (int i = 0; i < 1000; i++) {
            System.out.println("1024");
        }
    }

}

三、实现 Callable 接口,并结合 Future 实现

  • 首先定义一个 Callable 的实现类,并实现 call 方法。call 方法是带返回值的。
  • 然后通过 FutureTask 的构造方法,把这个 Callable 实现类传进去。
  • 把 FutureTask 作为 Thread 类的 target ,创建 Thread 线程对象。
  • 通过 FutureTask 的 get 方法获取线程的执行结果。
import java.util.Random;
import java.util.concurrent.Callable;

/**
 * 多线程实现的第三种方法,实现Callable接口 优点: 可以获取返回值 可以抛出异常
 */

//1.定义一个类实现Callable<V>接口
public class MyCallable implements Callable<Integer> {

    // 2.重写call方法
    @Override
    public Integer call() throws Exception {
        // 3.将要执行的代码写在call方法中
        //返回一个随机数
        Random r = new Random();
        int num = r.nextInt(100);

        return num;
    }
}

测试类:

MyCallable mc = new MyCallable();

//这里的泛型要跟MyCallable中的泛型一致
FutureTask<Integer> task = new FutureTask<>(mc);
//创建线程对象
Thread t = new Thread(task);
t.start();

//获取线程的运算结果
Integer result = task.get();
System.out.println(result);

lambda写法:

FutureTask<Integer> task = new FutureTask<>(() -> {
    Random r = new Random();
    int num = r.nextInt(100);

    return num;
});
//创建线程对象
Thread t = new Thread(task);
t.start();

//获取线程的运算结果
Integer result = task.get();
System.out.println(result);

四、通过线程池创建线程

此处用 JDK 自带的 Executors 来创建线程池对象。

  • 首先,定一个 Runnable 的实现类,重写 run 方法。
  • 然后创建一个拥有固定线程数的线程池。
  • 最后通过 ExecutorService 对象的 execute 方法传入线程对象。

在这里插入图片描述

五、前三种创建线程方式对比

继承Thread

优点 : 可以直接使用Thread类中的方法,代码简单
缺点 : 继承Thread类之后就不能继承其他的类

实现Runnable接口

优点 : 即使自定义类已经有父类了也不受影响,因为可以实现多个接口
缺点 : 在run方法内部需要获取到当前线程的Thread对象后才能使用Thread中的方法

实现Callable接口

优点:可以获取返回值,可以抛出异常
缺点:代码编写较为复杂

参考链接

链接: 面试官问我:创建线程有几种方式?我笑了
链接: 多线程创建的三种方式对比

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值