zoukankan      html  css  js  c++  java
  • Java学习-7

    线程

    线程的调度:

        分时调度:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间。
        抢占式调度:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性) , Java使用的为抢占式调度。
    

    创建多线程的方式:

    方法一:创建Thread类的子类

    1.创建一个Thread类的子类
    2.在Thread类的子类中重写Thread类中的run方法,设置线程任务(开启线程要做什么?)
    3.创建Thread类的子类对象
    4.调用Thread类中的方法start方法,开启新的线程,执行run方法
    

    注意:void start()使该线程开始执行; Java虚拟机调用该线程的run方法。
    结果是两个线程并发地运行;当前线程(main线程)和另一个线程(创建的新线程,执行其run 方法)。
    多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。
    java程序属于抢占式调度,那个线程的优先级高,那个线程优先执行;同个优先级,随机选择一个执行。

    例:

    Thread类的常用方法_获取线程名称

    1.使用Thread类中的方法getName()
    String getName() 返回该线程的名称。
    

    2.可以先获取到当前正在执行的线程,使用线程中的方法getName( )获取线程的名称
    static Thread currentThread() 返回对当前正在执行的线程对象的引用。
    

    Thread类的常用方法_设置线程名称

    Thread类的常用方法_sleep方法
    让程序暂停多少毫秒,例:

    方法二:实现Runnable接口

    1.创建一个Runnable接口的实现类
    2.在实现类中重写Runnable接口的run方法,设置线程任务
    3.创建一个Runnable接口的实现类对象
    4.创建Thread类对象,构造方法中传递Runnable接口的实现类对象
    5.调用Thread类中的start方法,开启新的线程执行run方法
    


    方法2相比方法1的好处

    1.避免了单继承的局限性
    一个类只能继承一个类(一个人只能有一个亲爹),类继承了Thread类就不能继承其他的类。实现了Runnable接口,还可以继承其他的类,实现其他的接口
    2.增强了程序的扩展性,降低了程序的耦合性(解耦)
    实现Runnpble接口的方式,把设置线程任务和开启新线程进行了分离(解耦)
    

    所以在创建多线程的时候应该尽量使用第二种方法

    匿名内部类方式实现多线程

    目的:简化代码

    线程安全问题

    概述:当多个线程同时执行一个线程任务的时候,就会产生冲突,例:通过3个线程输出20至1,在多个线程运行时就会输出重复的数


    原理:当某一个线程抢到CPU的执行权并开始执行里面的代码时,就会暂时失去对CPU的控制权,就会导致其他线程抢到CPU并执行里面的代码

    解决办法:
    1.同步代码块
    2.同步方法
    3.使用Lock锁
    

    同步代码块

    通过创建一个锁对象,与synchronized代码块一同解决该问题,当第一个线程抢到CPU的执行权就会带着锁对象一同执行里面的代码,这时候就算其他线程抢到CPU的执行权,但是没有锁对象,所以就无法执行里面的代码,必须等第一个线程执行完归还锁对象,才能重新争夺锁对象

    同步方法

    定义一个同步方法,把可能出现安全问题的代码放进去

    使用Lock锁

    步骤

    1.在成员位置创建一一个ReentrantLock对象
    2.在可能会出现安全问题的代码前调用Lock接口中的方法Lock获取锁
    3.在可能会出现安全问题的代码后调用Lock接口中的方法unLock释放锁
    

    线程池

    如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。所以为了解决这一问题引入线程池的概念,即:一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。
    线程池的使用步骤:

    1.使用线程池的工厂类Executors里边提供的静态方法newFixedThreadPool生产一个指定线程数量的线程池
    2.创建一个类,实现Runnable接口,重写run方法,设置线程任务
    3.调用ExecutorService中的方法submit,传递线程任务(实现类),开启线程,执行run方法
    4.调用ExecutorService中的方法shutdown销毁线程池(不建议执行)
    


    Lambda表达式

    目的:简化面向对象的复杂格式
    使用前提:

    1.使用Lambda必须具有接口,且要求接口中有且仅有一一个抽象方法。
    无论是JDK内置的Runnable、Comparator 接口还是自定义的接口,只有当接口中的抽象方法存在且唯一时,才可以使用Lambda。
    2.使用Lambda必须具有上下文推断。
    也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。
    

    格式:(参数列表) -> {一些重写方法的代码};

    例:

  • 相关阅读:
    Leetcode 5
    DFS输出全排列
    Leetcode 461
    Leetcode 4
    Leetcode 3
    Leetcode 2
    Windows 10 Mac 为Vs Code配置C/C++环境
    机器学习 学习笔记(1) -- 初识机器学习
    MacBook Pro休眠掉电、耗电量大问题解决方案
    Oracle错误及解决方案
  • 原文地址:https://www.cnblogs.com/pzbangbangdai/p/12350064.html
Copyright © 2011-2022 走看看