• 多线程


    1.什么进程?
     *         值得就是正在运行的程序,是系统进行资源分配和调用的独立单位
     *         每一个进程都有它自己的内存空间和系统资源
    2.什么线程?
     *         是进程中的每个顺序控制流,是一条执行路径
     *         一个进行如果只有一条执行流程,则为单线程
     *         一个进程有多条执行路径,则为多线程
    3.什么是并行?什么是并发?
     *          前者是逻辑上同时发生,指在某一个时间内同时运行的多个程序
     *          后者是物理上同时发生,指在某一个时间内同时运行多个程序
    4.java的运行原理?
     *         由java命令启动JVM,JVM启动就相当于启动了一个进程
     *         接着该进程创建了一个主线程去调用main()方法
    5.需求:我们要实现多线程的一个程序,问   我们要如何进行实现?
     *         由于线程是依赖进程而 存在的,所以我们应该先创建一个进程出来,
     *         而进程是由系统进行创建的,所以我们应该去调用系统工程,创建一个进程
     *         java是不能直接去调用系统功能的,所以我们没办法直接实现多线程的程序
     *         但是呢,java可以去调用C/C++写好的程序来实现多线程的
     *         由C/C++去调用系统功能创建进程,然后由java去调用这个方法

    继承Thread类 步骤:
        1.自定义MyThread,继承Thread类
        2.在MyThread中重写run()方法
            为什么要重写run()方法?
                不是类中的所有代码都需要被线程去执行的.
                而这个时候呢,为了区分哪些代码能够被线程执行。java中提供了Thread类中的run()
                用来包含哪些被线程执行的代码
        3.创建对象
        4.启动线程

    run()  他是一个单线程,直接可以当做普通方法去使用,
    如果我想 执行一个多线程  那么另一个方法  start()
          
    问  start()和run的区别?
        run()仅仅是封装线程执行的代码,直接调用时可以是 一个普通的方法
        start()首先启动了进程,然后由jvm去调用该线程的run()方法

    Thread类的基本获取和设置线程的方法:
        1.public final String getName()  获取线程的对象名称
            2.public final void  setName(String name):设置线程的名称
    我们也可以通过构造方法去给线程起名称
    问:
        如果获取了main方法所在的线程名称?
        例如:针对如果不是Thread类的子类中如何获取线程名称对象呢?
        1public static Thread curretThread()  返回当前正在执行的线程名称
        2.Thread.curretThread().getName()

    我们要获取main()方法 所在的线程对象名称  如何解决?
        //遇到这种情况呢,Thread类提供了一个很好玩的方法
        1.public static Thread currentThread()  返回当前正在执行的线程对象

    线程的调度
        假如我们的计算机只有一个cpu,那么CPU在某一个时刻只能执行一条指令
        线程只有得到CPU时间片才能有使用权,才能执行指令
    线程的两种调度策略
        1.分时调度策略: 所有线程轮流的去使用CPU的使用权,平均进行分配,每个线程占用CPU的时间
        2.抢占式调度策略:优先让级别高的线程使用CPU,如果线程的优先级相同,那么他们会随机选择一个,优先级高的线程获取CPU
           时间片的调度策略会多一些.
            注意:java中用的就是抢占式调度模型

    优先级我们的线程是没有设置优先级的,肯定是有默认的优先级,
        在java中默认的优先级是5
        线程优先级的范围:1-10
        线程优先级仅仅表示线程获取的CPU时间片的几率高,但是要在次数比较多,或者多次运行的时候才能看见更好的效果

    设置线程优先级的方法?
        public final  void serPRriority(int NewPriority) : 更改线程对的优先级   

    线程的睡眠方法:
        public static void sleep(long milis):在指定的毫秒数内让当前正在执行的线程休眠(暂停一会再去执行)
    注意:
        在sleep中 传入值是毫秒值

    线程的加入方法:
            1.public final void  join():等待该线程或者终止
        大体的概念:
            我调用了这个方法,必须线程执行完毕之后,其他的线程才能调用

    线程的中断与结束方法:
        public final stop():让线程停止,过时间了,但是还可以使用
        public void interrupt():中断线程,把线程装填停止,并抛出一个INTERRUPTEDEXCEPTION

    创建线程的另一种方法 Runnable接口的类,该类也会去实现run()方法,然后可以分配该类的实例,

    实现Runnable接口实现Runnable接口的好处:
        1.可以避免由于JAVA当继承带来的局限性
        2.适合多个相同的程序的代码去处理同一个资源的问题,把线程同程序的代码、数据有效的进行分离,较好的体现了面向对象的设计思想

    实现Runable接口的步骤
        1.定义一个MyRunnable,实现Runable接口
        2.在MyRunnable中重写run()方法
        3.创建MyRunnable类的对象
        4.创建Thread类的对象,把MyRunnable对象作为构造方法的参数
        5.启动线程
    使用Runnable接口的好处:
        不影响MyRunnable继承其他的类

    同步锁的弊端1.效率比较低
        2.容易产生死锁
           例如:
        两个或者两个以上的线程在争夺资源的过程中,发生了一种互相等待的现象
          举例:
        中国人、美国人吃饭案例
        正常情况下:
            中国人:一双筷子
            美国人:一个刀一个叉
        现在的问题:
            中国人:一只筷子 一个刀
            美国人:一只筷子 一个叉
    线程之间的通信:
        针对同一个资源的操作有不同种类的类型
        只出不进:电影院卖票(八佰、金刚川)
        可进可出:早餐店(生产者:厨师  消费者:顾客)

    Lock锁背景 :
        虽然我们可以理解同步代码块和同步方法的所对象,但是我们并没有看见那块上了锁,并在哪里释放了锁
        为了更好更清晰的表达如何并如何释放锁,JDK5之后提供了一个新的锁对象,LOCK
                   lock是接口不能直接序列化,这里采用他的实现类ReentrantLock来实例化
    方法ReentrantLock创建一个ReentrantLock的实例
        加锁解锁的方法:
        方法名                说明
        void lock()       获得锁
        void unlock()   释放锁

    线程池线程池的基本背景
            程序启动一个新的线程成本是很高的,因为它涉及到与操作系统进行交互。而使用线程池可以很好的提高性能,尤其是
                 当程序中要创建大量的生存很短的线程时,就要考虑使用线程池
          线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中称为空闲状态,等待下一个对象来使用
         java内置支持线程池
        线程是使用进程的资源,所以每次开启一个线程,它的成本是比较高的,所以使用线程池,就能解决这个问题
        如何使用线程池?
        Executors工厂来产生线程池,如一下几个方法
        1.public static ExecutorService newCachedThreadPool()开启具有缓存功能的线程池
        2.public static ExecutorService newFixedThreadPool(int nThreads) 创建爱你多少个线程池
        3.public static ExecutorService newSingleThreadExecutor()创建单个的线程池
        
            这些方法的返回值是ExecutorService对象,该对象表示一个线程池..可以执行Runnable对象或者Callable对象代表的线程.
      步骤:
        1.创建线程池对象
        2.创建Runnable实例
        3.提交Runnable实例
        4..关闭线程池
    线程池的好处
        线程池里面的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲装填,等待下一个对象来使用

    实现Callable接口好处
            1.可以有返回值
            2.可以抛出异常
        弊端
            代码比较复杂,所以一般不用

  • 相关阅读:
    ABP源码分析四十:ZERO的Application和Tenant
    ABP源码分析三十九:ABP.Hangfire
    ABP源码分析三十八: ABP.Web.Api.OData
    ABP源码分析三十七:ABP.Web.Api Script Proxy API
    232. 用栈实现队列
    155. 最小栈
    725. 分隔链表
    328. 奇偶链表
    148. 排序链表
    143. 重排链表
  • 原文地址:https://www.cnblogs.com/comw/p/14204997.html
Copyright © 2020-2023  润新知