Java基础教程之多线程详细分析

在了解多线程之前,先来了解一下进程与线程之间的关系。

进程和线程:
  进程是指在系统中正在执行的一个程序,每个进程之间是独立的。
  线程是进程的一个基本执行单元。一个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程)

主线程:
  在Java程序中存在一个主线程(JVM线程),main方法自带的一个线程。
  之所以在系统进行多个程序的时候(QQ,web网页等),看似是在同步执行,那是因为cpu在进程中进行多线程的切换,cpu切换的速度之快让我们 觉得是在同步执行,其实在进程的执行过程中是存在一定的先后顺序的。

线程的执行原理:
  线程运行的结果每次都不同,因为多个线程都在获取cpu的执行权,cpu执行到了谁,谁就执行。
  明确一点:在某一时刻,只能有一个程序在运行(多核cpu除外)——也可以说多线程的运行行为是在互相抢夺cpu的执行权,同时cpu在做着快速的切换动作,已达到看似同时运行的结果。因此多线程的特性是随机性。

实现多线程的方式有两种:继承Thread类、实现Runnable接口

继承Thread类

  1、定义类继承Thread类

  2、复写Thread中的run()方法

     目的:将自定义代码写在run()方法中,让线程运行

  3、调用start()方法,启动线程,调用run()方法

public class ThreadTest extends Thread{
   
    @Override
    public void run(){    //复写Thread中的run方法
        for(int i=0;i<10;i++){
            System.out.print(" demo run");
        }
    }
 
}
class ThreadDemo{
    public static void main(String[] args) {
        ThreadTest dt = new ThreadTest();
        dt.start();    //调用start方法(启动线程,调用run方法)
        for(int i=0;i<10;i++){
            System.out.print("main run");
        }
    }
}

  代码解说:在这一个程序中,存在两个线程:main主线程和ThreadTest自定义线程。

  这两个线程同是在一个进程(程序)中执行,为确保程序的正常执行,因此在进程的内存空间中,开辟了两个线程空间,这两个线程空间在要执行的时候,都要获取cpu的执行权,所以,会互相的去抢夺cpu的执行权。会先抢到谁就执行。因此,这段程序的运行结果是随机的。

  意思就是说:运行结果一会是main run,一会是demo run。存在无序性。

 至于为什么要复写run方法,原因是:
  Thread用于描述线程,该线程就只定义了一个功能,用于存储线程要运行的代码,该存储功能就是run()方法。也就是说Thread中的run()方法,用于存储线程要允许的代码。

(主线程的代码写在main方法中,而main方法是JVM定义的。所以JVM调用main方法的原因是因为主线程要使用,如果将自定义的代码写在main方法中,让JVM去执行,那就是一种单线程(主线程),不是多线程了。)

public class ThreadTest extends Thread{
    @Override
    public void run(){
        for(int i=0;i<10;i++){
            System.out.print(" demo run");
        }
    }
 
}
class ThreadDemo{
    public static void main(String[] args) {
        ThreadTest dt = new ThreadTest();
        dt.start();  //①
                dt.run();  //②
        for(int i=0;i<10;i++){
            System.out.print("main run");
        }
    }
}

  代码解说:在上段程序中,如果①被注释掉,直接dt.run(),那这就不是一个多线程的执行,只是相当于一个简单的对象调用方法,而线程创建了,并没有运行。

       所以,如果②被注释掉,直接dt.start(),那就是创建了一个线程对象dt,然后dt.start()将线程dt开启,并调用了run()方法,让线程去运行。

实现Runnable接口

  1、定义类实现Runnable接口

  2、复写Runnable接口中的run()方法

  3、通过Runnable建立线程对象

  4、将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/950885b733d5a42a63de22038f7abb59.html