多线程1(面试题--常见的线程创建方式)

1.创建子类,继承Thread,重写run方法

2.创建子类,实现Runnable接口,重写run方法

3.继承Thread,使用匿名内部类

4.实现Runnable,使用匿名内部类

5.lambda表达式(推荐)


继承Thraed重写run

步骤:继承->重写->实例->启动

缺点:线程和任务绑定在一起

java 复制代码
//1.继承
class MyThread extends Thread{
    //2.重写

    @Override
    public void run() {
        while (true){
            System.out.println("hello thread");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }
}
public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        //MyThread thread = new MyThread();

        //3.实例
        Thread thread = new MyThread();

        //4.启动
        thread.start();

        while (true){
            System.out.println("hello main");
            Thread.sleep(2000);
        }
    }
}

实现Runnable重写run

步骤其实大差不差,区别在于,不仅要实例化Thread对象,还要实例化Runnable对象,将Runnable对象作为参数传给Thread

通俗一点来说就是,Runnable是单独描述线程要执行的任务的,此时与线程没关系,将其作为参数传给Thread就是告诉线程所要执行的任务是什么,两者之间解耦合度更高,而第一种方法是将线程和任务绑定在了一起,耦合度更高

java 复制代码
class MyRunnable implements Runnable{

    @Override
    public void run() {
        while (true){
            System.out.println("hello thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
public class Demo2 {
    public static void main(String[] args) throws InterruptedException {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);

        thread.start();

        while (true){
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}

3.继承Thread,使用匿名内部类

本质上跟第一种方法没区别,只不过使用了匿名内部类来创建线程,好处就在于这个类是一次性的,只使用一次,也就是跟着当前线程一起,线程结束,类也结束

java 复制代码
public class Demo3 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(){
            @Override
            public void run() {
                while (true){
                    System.out.println("hello thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };
        t.start();//真正创建线程

        while(true){
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}

4.实现Runnable,使用匿名内部类

java 复制代码
public class Demo4 {
    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    System.out.println("hello thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });
        t.start();

        while (true){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

注意写法即可


5.lambda表达式

这是更推荐的一种做法,更加简洁

java 复制代码
public class Demo5 {
    public static void main(String[] args) {
        //lambda
        Thread thread = new Thread(()->{
           while (true){
               System.out.println("hello thread");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
           }
        });
        thread.start();

        while (true){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

使用lambda表达式需要注意的是变量捕获的情况:final 事实final(没有被修改的变量)


问题:为什么在继承或实现Runnable的时并不需要导包呢?

是因为他们都属于lang包底下,在Java中,lang包会默认导入到项目中,因此不需要手动import

这是基于管理方便的缘故,用什么类就导入什么包,但也存在这种方便的,默认自动导入的lang包

相关推荐
庞轩px2 小时前
第七篇:Spring扩展点——如何优雅地介入Bean的创建流程
java·后端·spring·bean·aware·扩展点
代钦塔拉2 小时前
Qt4 vs Qt5 带参数信号槽的连接方式详解
开发语言·数据库·qt
tongluowan0074 小时前
一个请求在Spring MVC 中是怎么流转的
java·spring·mvc
夜郎king4 小时前
Spring AI 对接大模型开发易错点总结与实战解决办法
java·人工智能·spring
InfinteJustice4 小时前
踩坑分享C 语言文件操作全攻略:从基础读写到随机访问与缓冲区原理
c语言·开发语言·microsoft
码云数智-大飞4 小时前
滥用Lombok的@EqualsAndHashCode导致线上事故复盘
开发语言
yong99904 小时前
C# 实时查看硬件使用率(CPU 内存 硬盘 网络)
开发语言·网络·c#
oradh4 小时前
Oracle数据库中的Java概述
java·数据库·oracle·sql基础·oracle数据库java概述
组合缺一5 小时前
Java AI 框架三国杀:Solon AI vs Spring AI vs LangChain4j 深度对比
java·人工智能·spring·ai·langchain·llm·solon
不午休の野猫5 小时前
vs + qt环境编译.sln项目时报无法解析的外部符号metaObject && qt_metacast
开发语言·qt