多线程的实现

目录

进程和线程

并发和并行

继承实现Runnable接口的Thread类实现的多线程

实现Runnable接口创建线程类

线程常用方法


进程和线程

进程:一个程序的启动就可以抽象化为一个进程
多线程的实现_第1张图片

线程:线程是由进程开启的,一个进程可以创建多个线程,多个线程同时运行
多线程的实现_第2张图片

并发和并行

并发:同一时刻,多个任务交替执行。简单说,单核CPU执行多任务就是并发。

并行:同一时刻,多个CPU可以实现多个任务,可以实现并行。

并发和并行的比较:
多线程的实现_第3张图片

继承实现Runnable接口的Thread类实现的多线程

  • 一个类继承Thread线程类,该类就可以当作线程类使用
  • 在继承Thread类的类中,需要重写Runnable下的run方法,在该方法的内部实现自己的业务逻辑
  • run方法会在调用start方法时由JVM隐式调用
  • 多个线程之间的逻辑会交替执行,当所有的线程逻辑执行结束后,进程才结束

继承Thread类的Fun类的功能的实现:

public class ThreadTestDrive {
    public static void main(String[] args) throws InterruptedException {
        Fun fun = new Fun();
        fun.start();    //调用start方法隐式调用run方法
        for (int j = 1; j <= 40; j++) {
            System.out.println("j" + " " + j + "---" + Thread.currentThread().getName());
            Thread.sleep(1000);
        }
    }
}

class Fun extends Thread {
    @Override
    public void run() {    //覆写run方法
        for (int i = 1; i <= 60; i++) {
            System.out.println("i" + " " + i + "---" + Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

线程逻辑/多线程机制:
多线程的实现_第4张图片

 为什么是start而不是run?

不妨直接调用下run方法,会发现程序总是在执行完run方法中的逻辑后才继续向下执行,在这里起始没有新线程的产生,而只是单纯的调用了fun对象的run方法:
多线程的实现_第5张图片

再来看下start方法的源码:
多线程的实现_第6张图片

会发现调用start方法的本质是调用了start0底层方法,start0方法由JVM调用操作特定类型操作系统中的函数完成新线程的启动,可以理解为start调用了start0方法,start0方法在底层开启新线程执行了run方法中的逻辑。值得注意的是,每一种操作系统都有自己特定的一套算法响应start0方法的逻辑。

多线程的实现_第7张图片

实现Runnable接口创建线程类

有了Thread类,为什么还要有Runnable接口?

为了解决Java的单继承缺陷。如果一个类继承了除Thread类外的另一个类,那么该类就无法在继承Thread类,也就无法创建新的线程。使用Runnable接口可以解决这个问题。同时Runnable接口实现的线程类更适合于多线程共享资源的情况(t3):

实现Runnable接口创建线程类Fun:

public class RunnableTestDrive {
    public static void main(String[] args) throws InterruptedException {
        Fun fun = new Fun();//实现了Runnable接口的Fun类的实例化对象
        //静态代理
        Thread thread = new Thread(fun);
        thread.start();
        for(int i=1;i<=40;i++) {
            System.out.println(i + "===" + Thread.currentThread().getName());
            Thread.sleep(1000);
        }
    }
}

class Fun implements Runnable {
    @Override
    public void run() {
        for (int i = 1; i <= 40; i++) {
            System.out.println(i + "---" + Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

Runnable创建线程的逻辑:

多线程的实现_第8张图片

 模拟Thread类的静态代理作用:

class ThreadSimulate {
    private Runnable target;
    public ThreadSimulate(Runnable target) {
        this.target = target;
    }
    public void start() {
        start0();
    }
    public void start0() {
        run();
    }
    public void run() {
        if(target != null) {
            target.run();
        }
    }
}

多线程的实现_第9张图片

线程常用方法

  • 线程退出
    线程退出有两种方式,run方法执行结束后退出和在外接控制变量的方式结束run方法的执行:
    public class RunMethodToSucceed implements Runnable {
        private boolean loop = true;//控制run方法中循环的变量
        @Override
        public void run() {
            while(loop) {
                System.out.println(Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        public void setLoop(boolean loop) {
            this.loop = loop;
        }
    }
    
  • 线程中断
    public void isInterrupted()判断线程是否中断
    public void interrupt()中断线程的执行(提前结束线程的休眠)

  • 线程礼让
    是指将当前CPU的调度资源让给其他线程使用,当前线程等待下次调用,当CPU资源充足时,礼让可能不会起作用。
    public static void field()
    多线程的实现_第10张图片

  • 线程强制执行
    public void join()将当前线程的执行进程加入到线程队列的最前面,并且等到该线程执行结束后才去执行其他的线程。
    多线程的实现_第11张图片

  • 设置/获取线程优先级
    CPU会根据线程的优先级优先调度,那个线程的优先级高,最有可能先被调度。
    public static final int MIN_PRIORITY = 1;
    public static final int NORM_PRIORITY = 5;
    public static final int MAX_PRIORITY = 10;
    pulbic void setPriority()设置线程的优先级
    public void getPriority()获取线程的优先级

  • 线程睡眠
    pulbic static void sleep()

  • 设置守护线程
    用户/工作线程和守护线程:
    用户/工作线程:执行完任务退出或者接收到通知退出。
    守护线程:一般为工作线程服务,当所有的用户线程结束,工作线程结束,常见的守护线程有垃圾回收机制

线程的七大状态

创建状态new:在new Thread之后,没有start之前,线程都属于创建状态。

运行状态Runnable:运行状态又分为就绪ready运行running状态,这两种状态取决于CPU的调度。
阻塞状态Blocked
等待状态waitting:等待另一个线程执行特定特定动作的线程处于此状态。
超时等待状态timed waitting:等待另一个线程执行指定动作达到指定时间的线程的状态。
终止状态terminated:线程的run方法执行结束后处于的状态

多线程的实现_第12张图片

你可能感兴趣的:(Java高级特性,java,开发语言)