zoukankan      html  css  js  c++  java
  • 用代码说话:如何在Java中实现线程

    并发编程是Java语言的重要特性之一,“如何在Java中实现线程”是学习并发编程的入门知识,也是Java工程师面试必备的基础知识。本文从线程说起,然后用代码说明如何在Java中实现线程。

    一、什么是线程?

    线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,也可以使用多线程对运算密集型任务提速。如果使用得当,线程可以有效地降低程序的开发和运维成本,同时能够提升程序的性能。

    二、线程和进程有什么区别?

    线程是进程的子集,一个进程可以有很多线程。每个进程都有自己的内存空间,可执行代码和唯一进程标识符(PID)。

    每条线程并行执行不同的任务。不同的进程使用不同的内存空间(线程自己的堆栈),而所有的线程共享一片相同的内存空间(进程主内存)。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。

    三、如何在Java中实现线程?

    “如何在Java中实现线程”是学习并发编程入门的必备知识,对于这个问题也是众说纷纭?打开百度搜索一下,一看便知。在信息爆炸的时代,我认为像孙悟空一样有一双火眼金睛是很必要的,分辨出哪些观点更加准确,才能少走弯路。

    那究竟有几种方法可以实现线程?哪一家的言论更权威,被更多的开发者所认同呢?毋庸置疑,当然是官网文档了。文档地址

    如图中所示:

    There are two ways to create a new thread of execution.

    One is to declare a class to be a subclass of Thread. ...

    The other way to create a thread is to declare a class that implements the Runnable interface. ...

    现在可以肯定地说,在Java中实现线程有两种方式, 分别是继承 Thread 类和实现 Runnable 接口。下面分别用两种方式实现线程。

    • 方法一:继承Thread类。
    public class MyThread extends Thread {
    
        public static void main(String[] args) {
            new MyThread().start();
        }
    
        @Override
        public void run() {
            System.out.println("用Thread类实现线程");
        }
    }
    
    
    • 方法二:实现Runnable接口。
    public class MyRunnable implements Runnable {
    
        public static void main(String[] args) {
            Thread thread = new Thread(new MyRunnable());
            thread.start();
        }
    
        @Override
        public void run() {
            System.out.println("用Runnable接口实现线程");
       }
    }
    
    • 深入分析

    深入去看Thread类的源码,可以看到Thread类实现了Runnable接口。

    并且Thread类重写了run方法, run 方法的代码如下:

    看过源码可以发现,其实两种方法实现线程的本质是一样的,都是最终调用了 start()方法来新建线程。这两个方法的最主要区别在于 run()方法的内容来源:

    继承Thread类: run()方法整体被重写;

    实现Runnable接口:最终调用 target.run()。

    四、实现 Runnable 接口和继承 Thread 类哪种方式更好?

    Runnable和Thread两者最大的区别是Thread是类而Runnable是接口,至于用类还是用接口,取决于继承上的实际需要。Java类是单继承的,实现多个接口可以实现类似多继承的操作。

    使用继承 Thread 的方式的话,那么每次想新建一个任务,只能新建一个独立的线程,而这样做的损耗会比较大。而如果采用实现Runnable接口的话,Runnable就相当于一个作业,而Thread才是真正的处理线程,我们需要的只是定义这个作业,然后将作业交给线程去处理,这样就达到了松耦合,也符合面向对象里面组合的使用。

    五、总结

    当下次再遇到这样的面试题的时候,可以这样硬刚面试官:

    Java官方文档说明有两种方式实现线程:继承Thread和实现Runnable接口。

    但是深入源码会发现,其实是一种本质方式,只能通过新建Thread类来创建线程,但是类里面的run方法有两种方式来实现,第一种是重写run方法,第二种实现Runnable接口的run方法,然后再把该runnable实例传给Thread类。

  • 相关阅读:
    java中的 equals 与 ==
    String类的内存分配
    SVN用命令行更换本地副本IP地址
    npoi 设置单元格格式
    net core 微服务框架 Viper 调用链路追踪
    打不死的小强 .net core 微服务 快速开发框架 Viper 限流
    net core 微服务 快速开发框架 Viper 初体验20201017
    Anno 框架 增加缓存、限流策略、事件总线、支持 thrift grpc 作为底层传输
    net core 微服务 快速开发框架
    Viper 微服务框架 编写一个hello world 插件02
  • 原文地址:https://www.cnblogs.com/sgh1023/p/11426858.html
Copyright © 2011-2022 走看看