多线程的实现

目录

进程和线程

并发和并行

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

实现Runnable接口创建线程类

线程常用方法


进程和线程

进程:一个程序的启动就可以抽象化为一个进程

线程:线程是由进程开启的,一个进程可以创建多个线程,多个线程同时运行

并发和并行

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

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

并发和并行的比较:

继承实现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);
            }
        }
    }
}

线程逻辑/多线程机制:

 为什么是start而不是run?

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

再来看下start方法的源码:

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

实现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创建线程的逻辑:

 模拟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();
        }
    }
}

线程常用方法

  • 线程退出
    线程退出有两种方式,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()

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

  • 设置/获取线程优先级
    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方法执行结束后处于的状态

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小s的s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值