JAVA之Thread类

一、主线程

主线程:执行主方法的线程(main)
JVM执行main(),main()会进入到栈内存,JVM会找操作系统开辟一条main方法通向CPU的执行路径
CPu就可以通过这个路径来执行main方法,而这个路径就叫做主(main)线程。

单线程程序:Java程序只有一个线程

Java程序属于抢占式调度,哪个线程的优先级高,就优先调度;同级随机调度。

二、如何多线程程序

创建多线程程序有两种方法。
1、一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。

创建多线程程序的第一种方式:创建Thread类的子类
java.lang.Thread类:是描述线程的类,需继承Thread类。

实现步骤:
1、创建一个Thread类的子类
2、在Thread类的子类中重写Thread类的run(),设置线程任务(开启线程要做什么)
3、创建Thread类的子类对象
4、调用Thread类的start(),开启新线程,执行run()
void start() 使该线程开始执行;JVM调用该线程的run()

Thread子类代码如下:

package test.day22Process;

/*
Java程序属于抢占式调度,哪个线程的优先级高,就优先调度;同级随机调度。

创建多线程程序的第一种方式:创建Thread类的子类
java.lang.Thread类:是描述线程的类,需继承Thread类

实现步骤:
1、创建一个Thread类的子类
2、在Thread类的子类中重写Thread类的run(),设置线程任务(开启线程要做什么)
3、创建Thread类的子类对象
4、调用Thread类的start(),开启新线程,执行run()
    void start() 使该线程开始执行;JVM调用该线程的run()

 */
public class Demo02Thread extends Thread {
    
    

    //设置线程的任务
    @Override
    public void run() {
    
    
        for (int i = 0; i < 20; i++) {
    
    
            System.out.println("run" + i);
        }
    }
}

测试代码如下:

package test.day22Process;

public class Main02 {
    
    

    public static void main(String[] args) {
    
    
        //创建Thread子类对象
        Demo02Thread th = new Demo02Thread();
        //开启多线程程序
        th.start();

        for (int i = 0; i < 20; i++) {
    
    
            System.out.println("main" + i);
        }
    }
}

在 Thread.class 文件中有这样一行代码:
private native void start0();
start()方法是一个native方法,它将通知底层操作系统,最终由操作系统启动一个新线程,操作系统将执行run()方法。

多线程内存图解如下:
在这里插入图片描述
多线程执行时,在栈内存中,其实每一个执行线程都有一片自己所属的栈内存空间。进行方法的压栈和弹栈。当执行线程的任务结束了,线程自动在栈内存中释放了。但是当所有的执行线程都结束了,那么进程就结束了。

2、另一种是实现Runnable接口方式

实现步骤:
1、创建Runnable接口的实现类
2、在实现类中重写Runnable接口的run(),设置线程任务
3、创建一个Runnable接口的实现类对象
4、创建Thread类对象,构造方法传递Runnable接口的实现类对象

优点:
1、避免了单继承的局限性
由于一个子类只能有唯一的一个父类,一旦继承了Thread类就无法继承其他的父类。但是,使用Runnable接口,可以实现其余的接口。
2、增强了程序的扩展性,降低了程序的耦合性(解耦)
实现Runnable接口的方式,把设置线程任务和开启新线程进行了分离。实现类中,重写了run():用来设置线程任务。创建Thread类对象,调用start():用来开启新的线程(实现多线程)。

5、调用Thread类的start(),开启多线程

Runnable接口的实现类代码如下:

package test.day22Process;

/*
创建多线程程序的第二种方法:实现Runnable接口

实现步骤
1、创建Runnable接口的实现类
2、在实现类中重写Runnable接口的run(),设置线程任务
3、创建一个Runnable接口的实现类对象
4、创建Thread类对象,构造方法传递Runnable接口的实现类对象
5、调用Thread类的start(),开启多线程
 */
public class Demo03Runnable implements Runnable {
    
    

    @Override
    public void run() {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            System.out.println(Thread.currentThread().getName() + "==>" + i);
        }
    }
}

测试代码如下:

package test.day22Process;

public class Demo03Main {
    
    

    public static void main(String[] args) {
    
    
        Demo03Runnable r = new Demo03Runnable();
        new Thread(r).start();

        for (int i = 0; i < 10; i++) {
    
    
            System.out.println(Thread.currentThread().getName() + "==>" + i);
        }
    }
}

三、Thread类

构造方法:
public Thread():分配一个新的线程对象。
public Thread(String name):分配一个指定名字的新的线程对象。
public Thread(Runnable target):分配一个带有指定目标新的线程对象。
public Thread(Runnable target,String name):分配一个带有指定目标新的线程对象并指定名字。

常用方法:
public String getName():获取当前线程名称。
public void start():导致此线程开始执行;Java虚拟机调用此线程的run方法。public void run():此线程要执行的任务在此处定义代码。
public static void sleep(long millis):使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)。
public static Thread currentThread():返回对当前正在执行的线程对象的引用。

四、Thread类和Runnable的区别

如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。
总结:实现Runnable接口比继承Thread类所具有的优势:
1.适合多个相同的程序代码的线程去共享同一个资源。
2.可以避免java中的单继承的局限性。
3.增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。
4.线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类。

扩充:
在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个JVM其实在就是在操作系统中启动了一个进程。

猜你喜欢

转载自blog.csdn.net/qq_44796093/article/details/109726648