Java多线程的介绍及创建1-1

想要知道什么是多线程,那么我们先了解一下什么是进程。

1.1 什么是线程?
    线程其实是进程中的一个实体,线程是不能单独存在的。进程则是代码在数据集合上的一次运行活动,
简单来说就是系统进行资源分配和调度的基本单位。线程则是进程的一个执行路径,一个进程中至少有一个
线程,进程中的多个线程共享进程的资源。
1.2 线程的创建及运行
    Java创建线程的方式有三种,分别为实现Runnable接口的run方法,继承Thread类并重写run方法,
还有使用FutureTask的方式。
  • 第一种: 继承Thread类的实现方式
     // 继承Thread类的方式
    public static class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println("继承Thread类的方式.");
        }
    }
    
    public static void main(String[] args) {
    
        // 创建线程
        MyThread myThread = new MyThread();
        // 启动线程
        myThread.start();
    }
    
    运行结果:
    在这里插入图片描述
    注意: 当创建完Thread对象后,该线程并没有被启动执行,而是调用了start方法后才真正启动线程。但是,start方法只是让线程处于就绪状态,需要获取CPU资源后才会真正的处于运行状态,而一旦run方法执行完毕,该线程就处于终止状态。

优点: 使用继承的方式好处在于可以直接在run()方法内使用this获取当前线程,而无需再使用Thread.currentThread()方法。

缺点: Java不支持多继承,如果继承了Thread类就无法继承其他类,另外任务与代码没有分离,当多个线程执行一样的任务时就需要多份代码。而Runable就没有这个限制。

  • 第二种: 重写Runnable接口的run的方式
   // 实现Runable接口
    public static class MyRunable implements Runnable {

        @Override
        public void run() {
            System.out.println("实现Runnable接口的方式");
        }
    }

    public static void main(String[] args) {

        MyRunable mr = new MyRunable();
        new Thread(mr).start();
        new Thread(mr).start();
    }

运行结果:
在这里插入图片描述
以上两个线程都使用了同一个mr代码逻辑,另外,MyRunable可以继承其他类,但是这两种方式都有同一个缺点,就是没有返回值。 下面再介绍最后一种,即FutureTask的方式。

  • 第三种: 使用FutureTask的方式
   // FutureTask的方式
    public static class CallerTask implements Callable<String> {

        @Override
        public String call() throws Exception {
            return "FutureTask的创建方式";
        }
    }

    public static void main(String[] args) {
        // 创建异步任务
        FutureTask<String> futureTask = new FutureTask<String>(new CallerTask());
        // 启动线程
        new Thread(futureTask).start();

        try{
            // 等待执行完毕并返回结果
            String result = futureTask.get();
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

运行结果:
在这里插入图片描述

上面代码中的CallerTask实现了Callable接口的call()方法,并使用创建的FutureTask对象作为任务,创建了一个线程,最后通过futureTask.get()拿到返回结果。

总结

使用继承的方式好处是方便传参。而使用Runnable接口的方式,则只能在主线程里面被声明为final的变量。前两中方式都没办法拿到任务的返回结果,但是FutureTask的方式就可以。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值