多线程八大核心知识体系笔记-1.线程创建的方式分析

多线程八大核心知识体系笔记-1.线程创建的方式分析,第1张

线程八大核心知识体系笔记-1.线程创建的方式分析

目录
  • 线程基础
    • 多线程创建方式
      • 正确的理解
        • Oracle官网验证
          • 两种实现方法
        • 方法一:实现Runnable接口,重写run()函数,运行start()方法(代码展示)
        • 方法二:继承Thread类,重写run()函数,运行start()方法(代码展示)
        • 两种方法的对比
          • 方法1(实现Runnable接口)更好的三个优势
            • 1.解耦性好,run方法业务与线程建立逻辑分离
            • 2.节约资源,每次新建任务无需每次都新建线程,例如线程池类
            • 3.可扩展性好,可用实现多继承接口,不能实现多继承类
          • 两种方法的本质对比
            • 1.Runnable整个run方法被重写
            • 2.Thread类最终调用target.run()
          • 若一个线程同时执行两种创建线程的方式什么结果?
        • 总结:最精准的描述
          • 通常分为2类
          • 准确地讲:一种创建线程方式、两种实现执行单元的方式
      • 其他实现形式,非本质区别
        • “线程池创建线程也算是一种新建线程的方式”
        • “通过Callable和FutureTask创建线程,也算是一种新建线程的方式”
        • “无返回值是实现runnable接口,有返回值是实现callable接口,所以callable是新的实现线程的方式”
        • 定时器

参考慕课网Java并发核心知识体系精讲课程

线程基础 多线程创建方式 正确的理解 Oracle官网验证 两种实现方法 方法一:实现Runnable接口,重写run()函数,运行start()方法(代码展示)
public class RunnableStyle implements Runnable{
    public static void main(String[] args) {
        RunnableStyle runnableStyle = new RunnableStyle();
        new Thread(runnableStyle,"runnableStyle").start();   
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}
方法二:继承Thread类,重写run()函数,运行start()方法(代码展示)
public class ThreadStyle extends Thread{
    public static void main(String[] args) {
        ThreadStyle thread1 = new ThreadStyle();
        thread1.setName("thread1");
        thread1.start();
        
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}
两种方法的对比 方法1(实现Runnable接口)更好的三个优势 1.解耦性好,run方法业务与线程建立逻辑分离
  • 表现1,这样创建不同的线程可以共享Runnnable实例中的变量和方法,即多个线程可以 *** 作同一资源,而Thread只能 *** 作当前对象的业务,即每新建一个线程类,当前资源类变量都会初始化
  • 代码实现区别:
    • 实现Runnable接口
public class RunnableStyle implements Runnable{
    public static void main(String[] args) {
        RunnableStyle runnableStyle = new RunnableStyle();
        new Thread(runnableStyle, "Runnable1").start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(runnableStyle, "Runnable2").start();
    }

    private int ticket = 25;
    @Override
    public void run() {
        ticket --;
        System.out.println(Thread.currentThread().getName() + ": " + "ticket: " + ticket);
    }
}
Runnable1: ticket: 24
Runnable2: ticket: 23
  • ​ 继承Thread类
public class ThreadStyle extends Thread{
    public static void main(String[] args) {
        ThreadStyle thread1 = new ThreadStyle();
        thread1.setName("thread1");
        thread1.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        ThreadStyle thread2 = new ThreadStyle();
        thread2.setName("thread2");
        thread2.start();
    }

    private int ticket = 25;
    @Override
    public void run() {
        ticket --;
        System.out.println(Thread.currentThread().getName() + ": " + "ticket: " + ticket);
    }
}
thread1: ticket: 24
thread2: ticket: 24
2.节约资源,每次新建任务无需每次都新建线程,例如线程池类 3.可扩展性好,可用实现多继承接口,不能实现多继承类 两种方法的本质对比 1.Runnable整个run方法被重写 2.Thread类最终调用target.run()
  • 1.继承的Thread类实现Runnable接口,重新的run方法最终调用Runnable实例target的run方法
...
public
class Thread implements Runnable {
...
@Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }
...
}
若一个线程同时执行两种创建线程的方式什么结果?
  • 则只执行Thread重写的方法,因为将父类重写的run方法覆盖了
public class DoubleStyle {
    public static void main(String[] args) {
        new Thread(() -> {
            System.out.println("来自 Runnable 的 run方法");
        }) {
            @Override
            public void run() {
                System.out.println("来自 Thread 的 run方法");
            }
        }.start();
    }
}
来自 Thread 的 run方法

总结:最精准的描述 通常分为2类 准确地讲:一种创建线程方式、两种实现执行单元的方式 其他实现形式,非本质区别 “线程池创建线程也算是一种新建线程的方式”
  • 线程池本质上,是创建有限个线程排队处理多于线程数量的业务,为了节省创建和销毁线程的时间
  • 本质上还是实现Runnable接口创建线程类
  • 源码片段:

“通过Callable和FutureTask创建线程,也算是一种新建线程的方式”
  • FutureTest类同时继承了Future接口和Runnnable接口,本质还是实现Runnnable接口中的run方法

“无返回值是实现runnable接口,有返回值是实现callable接口,所以callable是新的实现线程的方式”
  • 本质还是实现了Runnable接口的run方法

定时器
  • 本质也是实现Runnable接口


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5659352.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存