线程与多线程必会的知识

本文主要分为三个方面来介绍:

  • 线程和多线程
  • 线程的运行和创建
  • 线程的状态

1 线程与多线程

  线程是什么?线程(Thread)是一个对象(Object)。用来干什么?java线程(也称JVM线程)是java进程内允许许多个同时进行的任务。该进程内并发的任务成为线程(Thread),一个进程里至少一个线程。

   Java 程序采用多线程方式来支持大量的并发请求处理,程序如果在多线程方式执行下,其复杂度远高于单线程串行执行。那么多线程:指的是这个程序(一个进程)运行时产生了不止一个线程。

  为啥使用多线程?

  • 适合多核处理器。一个线程运行在一个处理器核心上,那么多线程可以分配到多个处理器核心上,更好地利用多核处理器。
  • 防止阻塞。将数据一致性不强的操作使用多线程技术(或者消息队列)加快代码逻辑处理,缩短响应时间。

聊到多线程,多半会聊并发与并行,咋理解并区分这两个的区别呢?

  • 类似单个 CPU ,通过 CPU 调度算法等,处理多个任务的能力,叫并发。
  • 类似多个 CPU ,同时并且处理相同多个任务的能力,叫做并行。

2 线程的运行与创建

2.1 线程的创建

java 创建线程对象有两种方法:

  • 继承Thread类创建线程对象。
  • 实现Runnable 接口类创建线程对象。

新建MyThread对象,代码如下:                                       

public class MyThread extends Thread {

    @Override // 可以省略
    public void run() {
        System.out.println("MyThread 的线程对象正在执行任务");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            MyThread thread = new MyThread();
            thread.start();

            System.out.println("MyThread 的线程对象 " + thread.getId());
        }
    }
}

    MyThread 类继承了 Thread 对象,并重写(Override)了 run 方法,实现线程里面的逻辑。main 函数是使用 for 语句,循环创建了 10 个线程,调用 start 方法启动线程,最后打印当前线程对象的 ID。

    run 方法和 start 方法的区别是什么呢? run 方法就是跑的意思,线程启动后,会调用 run 方法。 start 方法就是启动的意思,就是启动新线程实例。启动线程后,才会调线程的 run 方法。

    同理,实现Runnable接口类创建线程对象也很简单,只是不同的形式。新建的MyThreadBrother代码如下:

     public class MyThreadBrother implements Runnable {

    @Override // 可以省略
    public void run() {
        System.out.println("MyThreadBrother 的线程对象正在执行任务");
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(new MyThreadBrother());
            thread.start();

            System.out.println("MyThreadBrother 的线程对象 " + thread.getId());
        }
    }
}
2.2 线程的运行
在运行上面两个小 demo 后,JVM 执行了 main 函数线程,然后在主线程中执行创建了新的线程。正常情况下,所有线程执行到运行结束为止。除非某个线程中调用了 System.exit(1) 则被终止。

3.线程的状态
新建MyThreadinfo类,打印线程对象属性,代码如下:
public class MyThreadInfo extends Thread {

    @Override // 可以省略
    public void run() {
        System.out.println("MyThreadInfo 的线程实例正在执行任务");
//        System.exit(1);
    }

    public static void main(String[] args) {
        MyThreadInfo thread = new MyThreadInfo();
        thread.start();

        System.out.print("MyThreadInfo 的线程对象 \n"
                + "线程唯一标识符:" + thread.getId() + "\n"
                + "线程名称:" + thread.getName() + "\n"
                + "线程状态:" + thread.getState() + "\n"
                + "线程优先级:" + thread.getPriority());
    }
}

线程是一个对象,它有唯一标识符 ID、名称、状态、优先级等属性。线程只能修改其优先级和名称等属性 ,无法修改 ID 、状态。ID 是 JVM 分配的,名字默认也为 Thread-XX,XX是一组数字。线程初始状态为 NEW。

线程优先级的范围是 1 到 10 ,其中 1 是最低优先级,10 是最高优先级。不推荐改变线程的优先级,如果业务需要,自然可以修改线程优先级到最高,或者最低。

线程的状态实现通过 Thread.State 常量类实现,有 6 种线程状态:new(新建)、runnnable(可运行)、blocked(阻塞)、waiting(等待)、time waiting (定时等待)和 terminated(终止)。

线程状态流程大致如下:

  • 线程创建后,进入 new 状态
  • 调用 start 或者 run 方法,进入 runnable 状态
  • JVM 按照线程优先级及时间分片等执行 runnable 状态的线程。开始执行时,进入 running 状态
  • 如果线程执行 sleep、wait、join,或者进入 IO 阻塞等。进入 wait 或者 blocked 状态
  • 线程执行完毕后,线程被线程队列移除。最后为 terminated 状态。

 
posted on 2018-02-02 10:37  lynn669966  阅读(182)  评论(0)    收藏  举报