美文网首页java复习
2020-07-09多线程

2020-07-09多线程

作者: 智障猿 | 来源:发表于2020-07-09 16:49 被阅读0次

    概念介绍

    1. 进程:正在运行的程序
    • 是系统进行资源分配和调用的独立单位。
    • 每一个进程都有它自己的内存空间和系统资源。
    1. 线程:是进程中的单个顺序控制流,是一条执行路径
    • 单线程:一个进程如果只有一条执行路径,则称为单线程程序
    • 多线程:一个进程如果有多条执行路径,则称为多线程程序
    1. 线程调度
      线程有两种调度模型
    • 分时调度模型:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间片
    • 抢占式调度模型:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的CPU时间片相对多一些。
      Java使用的是抢占式调度模型

    多线程的实现方式

    • 夺多线程实现的方案有两种
      ①继承Thread类
      ②实现Runnable接口
    • 相比继承Thread类,实现Runnable接口的好处
      ①避免了Java单继承的局限性
      ②适合多个相同程序的代码处理同一资源的情况,把线程和程序的代码、数据有效分离,较好体现了面向对象的设计思想
    • 方式一:继承Thread类
      ①定义一个类MyThread继承Thread
      ②在MyThread类中重写run()方法
      ③创建MyThread对象
      ④启动线程,调用start()方法,虚拟机会自动调用run()方法
    1. 为什么要重写run方法?
      因为run()是用来封装被线程执行的代码。
    2. run()与start()的区别?
      run:封装线程执行的代码,直接调用,相当于普通方法的调用。
      start:启动线程;然后由JVM调用此线程的run方法。
    • 实现Runnable接口
      ①定义一个类MyRunnable实现Runnable接口
      ②在MyRunnable类中重写run()方法
      ③创建MyRunnable类的对象
      ④创建Thread类的对象,把MyRunnable对象作为构造方法的参数
      ⑤启动线程

    Thread类中设置和获取线程名称的方法

    ①void setName(String name):将此线程的名称改为等于参数name
    ②String getName():返回此线程的名称
    ③通过构造方法也可以设置线程名称。需要在自己创建的继承Thread的类中添加构造方法super()调用父类的构造方法

    获取main()方法所在的线程名称

    Thread类中的静态方法返回线程对象。
    public static Thread currentThread():返回当前正在执行的线程对象的引用
    Thread.currentThread().getName;

    Thread类中设置和获取线程优先级的方法

    • public final int getPriority():返回此线程的优先级
    • public final void setPriority(int newPriority):更改此线程的优先级
      ①线程默认优先级为5;
      ②线程优先级的范围是1-10;
      ③线程优先级高仅仅表示线程获取的CPU时间片的几率高。

    线程控制

    方法名 说明
    static void sleep(long millis) 使当前正在执行的线程停留(暂停执行)指定的毫秒数(static修饰,使用Thread.sleep(1000)调用)
    void join() 等待这个线程死亡
    void setDaemon(boolean on) 将此线程标记为守护线程,当运行的线程都是守护线程时,java虚拟机将退出

    线程生命周期

    线程的生命周期.png

    数据安全问题

    • 判断多线程程序是否会有数据安全问题的标准
      ①是否是多线程环境
      ②是否有共享数据
      ③是否有多条语句操作共享数据
    • 如何让解决多线程安全问题
      ①基本思想:让程序没有安全问题的环境
      ②把多条语句操作共享数据的代码锁起来,让任意时刻只能有一个线程执行即可,可以使用同步代码块实现
    • 同步代码块
      ①格式
    synchronized(任意代码){
      多条语句操作共享数据代码
    }
    

    ②synchronized(任意对象):就相当于给代码加锁了,任意对象可以看成一把锁

    public class SellTicket implements Runnable {
        private int ticketCount = 100;
        private Object obj = new Object();
        @Override
        public void run() {
            while (true) {
                synchronized (obj) {//不要在这里new一个对象,相当于给每个线程加了不同的锁,每个进程依然能执行下面的代码
                    if (ticketCount > 0) {
                        System.out.println(Thread.currentThread().getName() + "正在出售第" + ticketCount + "张电影票");
                        try {
                            Thread.currentThread().sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        ticketCount--;
                    }
                }
            }
        }
    }
    
    • 同步的好处和弊端
      ①好处:解决了多线程的数据安全问题
      ②弊端:当线程很多时,因为每个线程都会去判断同步上的锁,这是很消耗资源的,无形中会降低程序的运行效率
    • 同步方法
      同步方法:就是把synchronized关键字加到方法上
      ①同步方法的锁对象是:this
      同步静态方法的锁对象是:类名.class

    相关文章

      网友评论

        本文标题:2020-07-09多线程

        本文链接:https://www.haomeiwen.com/subject/gtcjcktx.html