多线程的三种实现方式

1、继承Thread类

创建一个任务类继承Thread类型,重新run方法表示一个具体的任务,在主方法中创建一个线程兑现(任务类对象),然后启动线程。

注:新线程的创建和启动都需要借助主线程

        一旦新线程启动之后,两个线程之间互不影响

        启动线程方法:start();

public class 设置线程名称 {
    public static void main(String[] args) {
        MyTread myThread = new MyThread();
        myThread.start();//借助主线程的帮助
        
         for (int i = 0; i < 10; i++) {
            System.out.println("主线程启动");
        }
    }
}

class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("新线程启动");
        }
    }

2、实现Runnable接口

        创造一个任务类实现Runnable接口,重写run方法表示需要执行的任务,创建一个任务类对象,表示一个具体任务,然后再创建一个Thread类的线程对象,将任务对象提交给线程对象。

public class 多线程的第二种实现方式{
    public static void main(String[] args) {
        //3、创建任务类对象
        MyRunable myRunable = new MyRunnable();
        //4、创建Thread对象,把任务类交给他
        Thread thread = new Thread(myRunnable);
        //5、开启线程
        thread.start();
        
        for (int i = 0; i < 1000; i++) {
            System.out.println("主线程.............");
        }
    }
}




//1、创建一个任务类实现Runnable接口
class MyRunnable implements Runnable{
    
    //2、重写run方法,表示具体的任务
    @Override
    public void run(){
        
        for(int i =0;i< 1000; i++){
            
            System.out.println("MyRunnable的run方法")
        }
    }

}

3、实现callable接口

创建一个任务类实现callable接口,重写call()方法,然后创建任务类对象,再创建Future的实现类FutureTask对象,把任务类对象作为构造方法的参数传递,创建Thread对象,把FutureTask对象作为构造方法的参数传递,最后启动线程。 get方法可以获取线程结束之后的结果。

callable接口可以定义返回值。


public class 多线程的第三种实现方式 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //3、创建任务类对象
        Mycallable mycallable = new Mycallable();
        //4、创建FutureTask对任务类进行包装(把任务类作为构造参数
        //传递给FutureTask)
        FutureTask<String> futureTask = new FutureTask<>(mycallable);
        //5、创建线程对象 传递futureTask
        Thread thread = new Thread(futureTask);
        //6、启动线程
        thread.start();
        //7、get方法可以获取任务类的返回值
        String str = futureTask.get();
        System.out.println(str);

    }
}

//1、定义一个任务类 实现Callable接口
class Mycallable implements Callable<String>{
    //2、重写call方法 表示具体的任务
    @Override
    public String call() throws Exception {
        for (int i = 1000; i >= 0; i--) {
            System.out.println("掉了"+i+"根头发");
        }
        return "掉完了,成了一个大光头";
    }
}

继承方式和实现方式的区别

1、代码复杂程度:

继承Thread方式简单
实现Runnable接口的方式比较复杂

2、实现原理:
继承Thread:

在调用start()方法时,底层会调用start0()方法,该方法是native修饰,表示的是本地的方法(是用C语言写的,所以看不见),然后回头再调用run方法,因为我们重写了run方法,最后执行的是我们重写后的run方法。

实现Runnable接口:

在创建Thread对象时,调用有参构造(Runnable任务类对象),一路调用init方法,最终将传进去的Runable任务对象赋值给自己的成员变量target,在嗲用start方法时,底层会调用start0方法(与继承Thread方法一致),该方法是native修饰,代表本地方法,回头再调用run方法,会进行if判断:判断自己的成员变量target是否为空,不为空则调用target,run()

3、设计层面:

java中只支持单继承,不支持多继承

继承方式:某个类继承了Thread类,那么就无法继承其他业务中需要的类型,就限制了我们的设计,扩展性较差。

实现方式:某个类通过实现Runnable的方式完成了多线程的设计,仍然可以继承当前业务中的其他类型,扩展性较强。

4、灵活性

继承方式:将线程对象和任务内容绑定在了一起,耦合性较强,灵活性较差。

实现方式:将线程对象和任务对象分离,耦合性就降低,灵活性增强:同一个任务可以被多个线程对象执行,某个线程对象也可以执行其他的任务对象。并且将来还可以将任务类对象,提交到线程池中运行;任务类对象可以被不同线程运行,方便进行线程之间的数据交互。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值