<多线程章节二>创建线程的几种常见方式

文章专栏

本篇文章收录于多线程,也欢迎翻阅博主的其他文章,可能也会让你有不一样的收获
JavaSE语法 数据结构 多线程

专栏导读

操作系统提供了一些API来操作线程,Java针对这些API进行了封装,所以只要掌握了这一套API就可以了,在Java中,JVM使用Thread类管理线程, 换句话讲,每一个Thread对象都对应一个线程,JVM将这些Thread对象组织起来进行调度执行, 想要使用线程,只要学习这个类中的方法就可以了

创建线程的五种方式

方法 解释
Thread() 创建线程对象
Thread(String name) 创建线程对象,并给线程命名,不会影响线程
Thread(Runnable runnable) 使用Runnable对象创建线程
Thread(Runnable runnable, String name) 使用Runnable对象创建线程并给线程命名

方式1.创建一个类,继承Thread

每一个线程都是一个单独的”执行流“, 都可以执行一段代码逻辑,但是,创建的线程从哪里开始执行呢???就需要提供一个入口,而run方法就是线程的入口,表示就从run方法这里开始执行;这一点就像是main方法一样,当运行一个Java程序时,就会从main方法开始执行代码;

此时,我们写的一个Java程序其实就是一个进程,一个进程里面至少要有一个线程,就是主线程,而在Java程序中,主线程的入口方法就是main方法;

//创建一个类,继承Thread
class MyThread extends Thread{
    //重写Thread里面的run方法,这个方法就是线程的入口
    @Override
    public void run() {
        //代码逻辑
    }
}
public class Demo1 {
    public static void main(String[] args) {
        
    }
}

但是,只有run方法还是不够的,run方法只是说明了线程从哪个地方开始执行,run方法里面只是定义了线程要做哪些任务,在主线程中,需要再调用start()方法来创建一个新的线程,线程创建后,再由线程调用run()方法开始执行任务;

//创建一个类,继承Thread
class MyThread extends Thread{
    //重写Thread里面的run方法,这个方法就是线程的入口
    @Override
    public void run() {
        System.out.println("线程正在工作");
    }
}
public class Demo1 {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();
        //run() 和 start() 都是Thread的方法
        //run()方法只是线程的入口
        //start()方法才是调用了系统API来创建一个线程,让线程再调用run来执行任务
    }
}

<多线程章节二>创建线程的几种常见方式_第1张图片

下面展示一个两个线程并发执行的情况:

class MyThread extends Thread{
    //重写Thread里面的run方法,这个方法就是线程的入口
    @Override
    public void run() {
        //写一个while循环让这个线程一直打印
        while(true) {
            System.out.println("hello Thread");
            try {
                //进行一个休眠方便观察
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        MyThread thread = new MyThread();
        thread.start();
        //写一个while循环,一直打印
        while(true) {
            System.out.println("hello main");
            //进行一个休眠方便观察
            Thread.sleep(1000);
        }
    }
}

<多线程章节二>创建线程的几种常见方式_第2张图片

上述结果就可以看到,两个线程分别在执行自己的代码,这也就印证了每一个线程都是一个单独的”执行流“, 本来在运行时只有一个执行流,但是遇见 thread.start() ,就开始了兵分两路”同时执行“, 就达到了并发编程的效果,而这里的并发指的是”并行+并发“, 因为,程序员在写代码的时候,是无法感知到这两个线程到底是在一个CPU核心上调度执行还是在两个CPU核心上同时执行, 所以在宏观上也就是我们人的肉眼看着都是在同时执行的,这一点在进程那篇文章中已经讲解的很清楚了,你可以去看一下

如果讲代码中的 thread.start() 改为 thread.run() 会发生什么呢?

<多线程章节二>创建线程的几种常见方式_第3张图片

如果改成thread.run(), 它就只剩下一个主线程了,只会按照代码的顺序依次执行,就成了一个单独的方法调用,这就不是多线程工作了,只有当run()方法结束后,才会继续向下执行;也就没有实现”并发编程”;也可以看到,Runnable类中也是只有一个方法run();

<多线程章节二>创建线程的几种常见方式_第4张图片

方式2.创建一个类,实现Runnable接口

使用Runnable接口和继承Thread的区别就是为了解耦合,比如说,有一些任务不一定是线程调度执行,也有可能是线程池或着其他等等,这时候就可以把这个任务给抽离出来,直接就可以用线程池或其他;

//创建一个类,实现Runnable接口
class MyThread2 implements Runnable{
    @Override
    public void run() {
        while(true) {
            System.out.println("hello Thread");
        }
    }
}
public class Demo2 {
    public static void main(String[] args) {
        //Runnable 就表示的是这是一个可执行的任务
        Runnable runnable = new MyThread();
        Thread thread = new Thread(runnable);
        
        thread.start();
        
        while(true) {
            System.out.println("hello main");
        }
    }
}

方式3.继承Thread,重写run(), 但是使用匿名内部类

这个类没有名字,所以叫匿名内部类,虽然没有名字但是也没有关系,因为这个类是一次性的,只知道这个类是Thread的子类,然后同时又进行了实例化,之后在子类中重写run() 方法;如果你不理解匿名内部类,可以我这篇文章


    public static void main(String[] args) {
        Thread thread = new Thread() {
            @Override
            public void run() {
                System.out.println("hello Thread");
            }
        };
        
        thread.start();
        System.out.println("hello main");
    }

方法4.实现Runnable,重写run(), 但是使用匿名内部类

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("hello Thread");
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
        System.out.println("hello main");
    }

方式5.使用Lambda表达式

    public static void main(String[] args) {
        
        Thread thread = new Thread(() -> {
            System.out.println("hello Thread");
        });

        thread.start();
        System.out.println("hello main");
    }

你可能感兴趣的:(开发语言,java,java-ee)