(一)线程的含义以及创建

154 阅读3分钟

一、线程和进程

1、进程

进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。进程是一种抽象的概念,从来没有统一的标准定义。进程一般由程序,数据集合和进程控制块三部分组成。程序用于描述进程要完成的功能,是控制进程执行的指令集;数据集合是程序在执行时所需要的数据和工作区;程序控制块包含进程的描述信息和控制信息是进程存在的唯一标志。
进程具有的特征:
动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生,动态消亡的;
并发性:任何进程都可以同其他进行一起并发执行;
独立性:进程是系统进行资源分配和调度的一个独立单位;
结构性:进程由程序,数据和进程控制块三部分组成;

2、线程

线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。一个标准的线程由线程ID,当前指令指针PC,寄存器和堆栈组成。而进程由内存空间(代码,数据,进程空间,打开的文件)和一个或多个线程组成。

3、线程和进程的关系

  1. 线程是程序执行的最小单元,而进程是操作系统分配资源的最小单位。
  2. 线程是进程的一部分,一个进程可以包含若干个线程。进程可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。
  3. 地址资源和其他资源:进程间相互独立,同一进程的个线程间共享。某进程内的线程在其他进程不可见。在引入线程的操作系统中,通常把进程作为分配资源的基本单位,把线程作为独立运行和独立调度的基本单位。
  4. 进程间通信:线程间可以直接读取进程数据段来进行通信。需要进程同步和互斥手段的辅助,以保证数据的一致性。
  5. 调度和切换:线程上下文切换比进程上下文切换快的多。

二、线程的实现方式

1、继承Thread类

继承Thread类,实现run()方法

public class ThreadOne extends Thread {
    @Override
    public void run() {
        System.out.println("创建线程方法一!");
    }

    public static void main(String[] args) {
        /**
         * 写法一
         */
        for (int i = 0; i < 100; i++) {
            ThreadOne threadOne = new ThreadOne();
            threadOne.start();
        }
        /**
         * 写法二(lambda)
         */
        Thread threadOne = new Thread(() -> System.out.println("创建线程方法一!"));
        threadOne.start();
    }
}

该方法实际上依靠实现Runnable接口实现,因为Thread类实现了Runnable接口

image.png

2、实现Runnable接口

实现Runnable接口,实现run()方法

public class ThreadTwo implements Runnable {

    private String s;

    public ThreadTwo(String s) {
        this.s = s;
    }

    @Override
    public void run() {
        System.out.println(s);
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            Thread threadTwo = new Thread(new ThreadTwo(i + ""));
            threadTwo.start();
        }
    }
}

建议使用实现Runnable的方法实现线程,因为在面向对象设计中,有一条约定俗成的规则:组合优于继承(Prefer composition over inheritance),继承只能单继承,但是接口可以多实现。

3、实现Callable接口

public class ThreadThree implements Callable<String> {
    private String s;
    public ThreadThree(String s) {
        this.s = s;
    }

    @Override
    public String call() throws Exception {
        System.out.println(s);
        return s;
    }

    public static void main(String[] args) throws Exception {
        ThreadThree threadThreeA = new ThreadThree("1");
        ThreadThree threadThreeB = new ThreadThree("2");
        ThreadThree threadThreeC = new ThreadThree("3");
        ThreadThree threadThreeD = new ThreadThree("4");

        String a = threadThreeA.call();
        String b = threadThreeB.call();
        String c = threadThreeC.call();
        String d = threadThreeD.call();
    }
}