创建线程的四种方式

创建线程的四种方式:

  • 继承Thread类
  • 实现Runnable接口
  • 实现Callable接口
  • 使用Executors工具类创建线程池

1、继承Thread类

  1. 定义一个Thread类的子类,重写run方法,将相关逻辑实现,run()方法就是线程要执行的业务逻辑方法
  2. 创建自定义的线程子类对象
  3. 调用子类实例的star()方法来启动线程
public class MyThread extends Thread {

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " run()方法正在执行...");
    }

}
public class TheadTest {

    public static void main(String[] args) {
        MyThread myThread = new MyThread(); 	
        myThread.start();
        System.out.println(Thread.currentThread().getName() + " main()方法执行结束");
    }

}

运行结果:

main main()方法执行结束
Thread-0 run()方法正在执行...

2、实现Runnable接口

  1. 定义Runnable接口实现类MyRunnable,并重写run()方法
  2. 创建MyRunnable实例myRunnable,以myRunnable作为target创建Thead对象,该Thread对象才是真正的线程对象
  3. 调用线程对象的start()方法
public class MyRunnable implements Runnable {

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " run()方法执行中...");
    }

}
public class RunnableTest {

    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();
        System.out.println(Thread.currentThread().getName() + " main()方法执行完成");
    }

}

运行结果:

main main()方法执行结束
Thread-0 run()方法正在执行...

3、实现Callable接口

  1. 创建实现Callable接口的类myCallable
  2. 以myCallable为参数创建FutureTask对象
  3. 将FutureTask作为参数创建Thread对象
  4. 调用线程对象的start()方法
public class MyCallable implements Callable<Integer> {

    @Override
    public Integer call() {
        System.out.println(Thread.currentThread().getName() + " call()方法执行中...");
        return 1;
    }

}
public class CallableTest {

    public static void main(String[] args) {
        FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyCallable());
        Thread thread = new Thread(futureTask);
        thread.start();

        try {
            Thread.sleep(1000);
            System.out.println("返回结果 " + futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " main()方法执行完成");
    }

}

执行结果:

Thread-0 call()方法执行中...
返回结果 1
main main()方法执行完成

什么是Callable和Future?
Callable接口类似于Runnable,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一点,被线程执行后,可以返回值,这个返回值可以被future拿到,也就是说Future可以拿到异步执行任务的返回值。
Future接口表示异步任务,是一个可能还没有完成的异步任务的结果。
所以Callable用于产生结果,Future用于获取结果。

4、使用 Executors 工具类创建线程池
Executors提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。

主要有newFixedThreadPool,newCachedThreadPool,newSingleThreadExecutor,newScheduledThreadPool,后续详细介绍这四种线程池

public class MyRunnable implements Runnable {

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " run()方法执行中...");
    }

}
public class SingleThreadExecutorTest {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        MyRunnable runnableTest = new MyRunnable();
        for (int i = 0; i < 5; i++) {
            executorService.execute(runnableTest);
        }

        System.out.println("线程任务开始执行");
        executorService.shutdown();
    }

}

运行结果:

线程任务开始执行
pool-1-thread-1 is running...
pool-1-thread-1 is running...
pool-1-thread-1 is running...
pool-1-thread-1 is running...
pool-1-thread-1 is running...

线程的run()和start()有什么区别?

  • 每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,run()方法成为线程体,通过调用Thread类的start()方法来启动一个线程。
  • start()方法用于启动线程,run()方法用于执行线程运行时的代码。run可以重复调用,而start()只能调用一次。
  • start()方法来启动一个线程,真正实现了多线程运行。调用start()方法无需等待run()方法体代码执行完毕,可以直接继续执行其他的代码;此时线程处于就绪状态,并没有运行。然后通过次Thread类调用方法run来完成其运行状态,run方法运行结束,此线程中止,然后CPU在调度其他线程。
  • run方法是在本线程中,只是线程的一个函数,而不是多线程。如果直接调用run方法,其实就是相当于调用另一个普通的函数而已,直接调用run()方法必须等待run()方法执行完毕才能执行下面的代码,所以执行路径只有一条,根本就没有线程的特征,所以在多线程执行时要使用start()而不是run()方法。

总结:调用start()方法可启动线程并使线程进入就绪状态,而run方法只是thread的一个普通方法调用,还是在主线程中执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值