34.线程概述

一、线程的原理

注意:已经开启的线程在运行的时候不能被再次开启,也就是说不能同时start同一个Thread对象!

每一个线程都有自己独立的方法栈!

垃圾回收线程就是一个守护线程

内存图解.png

二、Thread类

包位置java.lang.Thread

构造方法:(省略public)

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

常用方法(省略public)

  • static Thread currentThread(): 返回对当前正在执行的线程对象的引用。
  • String getName() : 获取当前线程名称。
  • void start() : 让此线程开始执行,Java虚拟机调用此线程的run方法。
  • void run() : 此线程要执行的任务在此处,相当于小main()方法(底层是调用的本地方法)。
  • final void join() : 等待当前子线程执行完再执行!
  • static void sleep(long millis):使当前正在执行的线程一指定的毫秒数暂停,睡一会儿再执行。

创建线程的两种方式:

  • 1.继承Thread类
    ①. 定义Thread类的子类;重写run()线程执行体。
    ②. 创建Thread子类的线程对象;
    ③. 调用对象start()方法。

  • 2.实现Runnable接口,(包位置:java.lang.Runnable;其实Thread就是实现了Runnable接口)
    ①. 定义Runnable接口实现类,重写run()执行体函数。
    ②. 创建Runnable实现类实例,以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
    ③. 调用线程对象的start()方法启动线程。

class MyRunnable implements Runnable {

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " 跑起来了。。。");
    }
}
/***********************************************/
public class Main {

    public static void main(String[] args) {
        MyRunnable mr = new MyRunnable();
        Thread t = new Thread(mr, "我的线程");
        t.start();
        System.out.println("主函数也跑起来了。。。。。");
    }
}

提示:

  • 1.实现Runnable,该类就具有多线程类的特征;
  • 2.当启动多线程的时候,都会先通过Thread类的构造方法Thread(Runnable target)构造出对象,然后调用Thread对象的start()方法来运行多线程代码。
  • 3.所有的多线程代码都是通过Thread的start()方法运行的,不管是继承Thread类还是实现Runnable接口实现多线程,最终都是通过Thread的本对象的API
    来控制线程的。(熟悉Thread类的API是进行多线程编程的基础)

Runnable对象仅仅作为Thread对象的target,Runnable实现类里面包含的run()方法仅作为线程执行体。而实际的线程对象依然是Thread实例,只是改Thread线程负责执行其target的run()方法。

三、Thread和Runnable的区别

注意: 如果一个类继承Thread,则不适合资源共享。但是如果实现了Runnable接口,则很容易实现资源共享。

实现Runnable接口比继承Thread类所具有的优势

  1. 适合多个相同的程序代码的线程去共享一个资源(实现Runnable接口的一段代码可被多个线程使用,可以实现安全性,而继承Thread类的方式不能共享)。
  2. 可以避免java中单继承局限性。(继承了Thread就不能继承其他类)
  3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。
    • 耦合性:代码和代码之间的关联性。
    • Runnable: 执行的代码和线程开启、设置线程名称。等功能分离
    • 开发原则:高内聚、低耦合;
  4. 线程池只能放入实现Runnable或Callable类线程不能直接放入继承Thread的类。

补充:每当使用java命令执行一个类,都会启动一个JVM, 每个JVM在操作系统中都是一个进程;一个Java进程至少启动两个线程,一个main线程,一个是垃圾收集线程;

推荐:使用匿名内部类的方式实现线程的创建

使用匿名内部类,可方便的实现每个线程执行不同的线程任务操作。

如下:

public class NoNameInnerClassThread {

    public static void main(String[] args){

        // 匿名内部类
        Runnable r = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName() + i + "...");
                }
            }
        };

        new Thread(r, "线程 NO.1  ").start();

        // Lamda表达式
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + i + ".........");
            }
        }, "线程 NO.2  ").start();
    }
}

补充:枚举类型

枚举类型就是枚举变量能够取的集合。

enum Weekday {
    星期一,星期二,星期三,星期四,星期五,星期六,星期日
}

你可能感兴趣的:(34.线程概述)