前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅谈Java线程

浅谈Java线程

作者头像
南风
发布2019-04-25 17:47:31
3560
发布2019-04-25 17:47:31
举报
文章被收录于专栏:Java大联盟Java大联盟

线程是程序开发中非常重要的一个技能点,无论你使用哪种语言都是绕不开的,作为一名程序猿,线程是你必须要掌握的,但是线程的概念不太好理解,尤其对于初学者来讲更是如此,今天我试图用更加通俗易懂的方式来为你讲解线程,一起来看看。

要搞清楚线程的概念,必须先搞清楚进程,什么是进程?百度百科的解释是:进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。这种官方解释准确但是不好理解,如何理解进程呢?简单来讲,计算机上正在运行的一个应用程序就是一个进程,比如我打开 IDEA 写代码就是一个进程,打开微信聊天就是一个进程等等,但是这里需要注意一个关键字:正在运行的,也就是说进程是一个动态概念,必须是正在运行的某个应用程序才能称得上是进程。

如果我在计算机上安装了 IDEA 应用程序,但是并没有启动它,那么就没有进程这一概念,所以进程是动态的,不是永久的,有创建有销毁,运行某个应用程序就表示创建了对应的进程,关闭该程序则表示进程销毁,如下图所示。

一个应用程序可以包含一个进程,也可以由多个进程组成。那么什么是线程呢?线程是进程的基本单位,一个进程由一个或者多个线程组成,搞清楚这个关系之后,我们可以明确线程就是程序执行的最小单元。

线程和进程一样,也是动态概念,有创建有销毁,存在只是暂时的,不是永久性的。进程与线程的区别在于进程在运行时拥有独立的内存空间,也就是说每个进程所占用的内存都是独立的。而多个线程是共享内存空间的,但是每个线程的执行是相互独立的,线程必须依赖于进程才能执行,单独的线程是无法执行的,由进程来控制多个线程的执行,没有进程就不存在线程。

那么什么是多线程呢?一个进程中同时有多个线程在执行就是多线程,有一个很简单的方法来判断程序是单线程还是多线程:把程序的整个运行流程画出来,如果是一条回路则是单线程,如果是两条或两条以上的回路则是多线程,比如下面这段代码。

代码语言:javascript
复制
public class Test {
     public static void main(String[] args) {
         Test2 test2 = new Test2();
         test2.test();
         for (int i=0;i<100;i++){
             System.out.println("++++++++++++Test");
         }
     }
}

class Test2{
     public void test(){
         for (int i=0;i<100;i++){
             System.out.println("------Test2------");
         }
     }
}

这段代码是单线程,这个线程就是 main 方法,按照上述所讲的方式来画出这段程序的运行流程,如下图所示。

只有一条回路,即单线程,两个不同的业务逻辑需要按顺序来排队执行,执行完 Test2 的循环之后,才能执行 Test 的循环,如果是两个线程,应该是什么样的回路呢?如下图所示。

可以看到,两个线程即表示两个不同的业务逻辑是同时在向下执行的,不需要谁等待谁,那么上述的多线程代码如何来实现呢?Java 中实现多线程有两种方式。

1、继承 Thread 类

具体的操作是创建一个类,让其继承 Thread,什么是 Thread?Thread 是由 Java 提供给开发者的一个父类,用来描述线程,我们知道线程是一个概念,Thread 就是 Java 来描述这个概念的类,Thread 的实例化对象就是某个具体的线程,Thread 的源码如下图所示。

可以看到 Thread 类实现了 Runnable 接口,Runnable 接口的定义非常简单,只有一个抽象方法 run,如下图所示。

这个接口的作用是什么呢?我们知道 Java 中的接口表示某种功能,一个类实现了某个接口就表示该类具备了某种功能,所以 Runnable 接口是描述什么功能的呢?这里首先要搞清楚线程和任务的概念,一句话来解释:线程是执行任务的具体对象。

我们说过线程是程序执行的最小单元,每个线程都是在执行某个任务,多个任务汇总之后就是一个完整的程序执行,所以线程存在的意义就是要执行某个任务,任务不是一个实体,只是一种描述,线程是落实这种描述的实体。比如现在需要找个人帮你取快递,这就是一个任务,交给张三完成,张三就是执行任务的实体,即张三是线程对象,取快递是任务。

搞清楚线程和任务的关系之后再来看 Runnable 接口,可以简单理解为让某个类具备执行任务的功能,所以 Thread 类需要实现该接口,它的实例化对象就具备了执行任务的功能。Thread 类中定义了各种线程相关方法,如启动线程,线程调度等等,所以我们自定义的类只需要继承 Thread 类就拥有了线程的各种操作方法,具体实现如下所示。

代码语言:javascript
复制
class Test2 extends Thread{
     @Override
     public void run() {
         for (int i=0;i<100;i++){
             System.out.println("------Test2------");
         }
     }
}

这里对 run 方法进行了重写,因为不同的线程对象需要执行不同的业务,而 Thread 类只是提供了一个模版,需要其子类根据具体需求完成重写,线程类创建完成就可以使用了,如下所示。

代码语言:javascript
复制
public class Test {
     public static void main(String[] args) {
         Test2 test2 = new Test2();
         test2.start();
         for (int i=0;i<100;i++){
             System.out.println("++++++++++++Test");
         }
     }
}

class Test2 extends Thread{
     @Override
     public void run() {
     for (int i=0;i<100;i++){
         System.out.println("------Test2------");
         }
     }
}

分析一下 Test 的 main 方法,main 方式是这段程序的主线程,我们在主线程中创建了一个子线程对象 test2,然后通过 start 方法启动子线程,这样主线程和子线程就开始争夺 CPU 资源,所呈现的结果就是两个 for 循环在交替执行,如下图所示。

2、实现 Runnable 接口

相比较于第一种方法,实现 Runnable 接口实质上是将方法一的实现进行了拆分,什么意思呢?我们说过线程需要和任务结合起来,由线程来执行任务,具体到 Java 程序中,Runnable 接口表示可执行任务,Thread 类本身就实现了该接口,即已经把任务绑定给了线程。而第二种方法的意思是单独创建一个任务对象,和线程分开,分别实例化任务对象和线程对象,再把任务交给线程,具体实现如下所示。

代码语言:javascript
复制
public class Test {
     public static void main(String[] args) {
         Test2 test2 = new Test2();
         Thread thread = new Thread(test2);
         thread.start();
         for (int i=0;i<100;i++){
             System.out.println("++++++++++++Test");
         }
     }
}

class Test2 implements Runnable {
     @Override
     public void run() {
         for (int i=0;i<100;i++){
             System.out.println("------Test2------");
         }
     }
}

此时的 test2 对象不是线程,只是描述线程要执行的任务,所以需要额外创建线程对象 thread,把 test2 任务交给它,这样线程才有意义,没有具体任务的线程是无意义的,然后启动该线程对象即可。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java大联盟 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档