多线程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包

相关推荐
怕浪猫14 小时前
分享一个做视频的skill,这条白板视频,每一笔都是代码画的
前端·javascript·面试
FYKJ_201014 小时前
springboot助农产品销售商城05829-计算机课程设计、毕业设计
java·spring boot·python·mysql·spark·django
Yunovian15 小时前
AI时代,针对模型与应用,浅谈一下各编程语言
开发语言·c++·人工智能·python·ai·rust·ai编程
周杰伦fans16 小时前
构建真正智能的CAD AI绘图代理
开发语言·人工智能·c#
弈栈录16 小时前
基于 Spring Boot 构建生产级 AI 应用平台
后端·面试·架构
user_admin_god17 小时前
第 10 篇:拼上下文与生成——预算、边界与防幻觉
java·人工智能·spring boot·语言模型
用户31268748772017 小时前
GC 算法与垃圾收集器演进:从 Serial 到 ZGC
java
天天被压力17 小时前
【别再到处找免费股票数据API了:官方204个接口,32篇一次讲透 #02】涨停跌停与特色股池:5类股池接口一次拉全
java·人工智能·python
斯维赤18 小时前
从 @Tool 到 Agent 流水线:LangChain4j 进阶教学,一个库打全套
java·后端
zhanghaha131418 小时前
Python进阶教程:35_PyQt (保姆级零基础教程)
开发语言·python·pyqt