• 20200415_多线程——重点是应用场景


    进程&线程

    【1】一个程序会产生一个进程

    【2】一个进程当中,可以有若个线程

    【3】线程的执行,是在CPU当中进行高速的资源切换

    【4】线程的执行、等待的时间,通常和CPU的运行性能和CPU的内核数有必然关系

    线程创建方式

    【1】对Thread类进行派生并覆盖run()方法

    【2】通过实现Runnable接口创建

    JVM

    【1】主线程:在Java当中,main()方法。

    【2】子线程:每创建一个线程,就会产生一个新的调用栈。

    【3】用户线程:在执行过程当中,虚拟机不关闭

    【4】守护线程:当某个程序的用户线程全部执行完毕后,守护线程立刻停止

    线程实例化

    【1】new Thread()  new Thread(naeme)  new Thread(new MyRunnable())

    【2】start()方法,线程执行。

    【3】Thread.currentThread().getName()

    【4】start()方法启动线程之后,线程进入到预备执行状态。等待CPU分配资源,只有资源分配到了,才开始执行。

    【5】run()方法只是一个普通的方法调用。

    【6】sleep()、join() ---> otherwise blocked

    【7】wait() ---> blocked in wait poll

    【8】synchronized ---> blocked in lock poll

    【9】 wait poll ----> notify() ---->lock poll  ; blocked  ----> sleep时间到 &&& 获得锁 ---->runnable 【只要是阻塞状态一定会回到可执行状态】;

    【10】线程执行的(瞬时状态)——顺序是不可控的。

    线程使用

    【1】start()只能被调用一次,调用两次以上就会报错。

    【2】尽管采用线程队列,但是依旧无法控制线程调度程序。

    【3】线程和线程之间是相互独立的,各自有对应的栈空间——数据区。

    【4】线程调度

         -等待和唤醒:必须在同步状态下,给某个方法加同步锁,保证该方法。

         -必须在同步状态下,才能 wait()

         -this.wait():对象执行该方法

         -等待可以被唤醒。this.notify(),也可以自己结束 this.wait(1000)[设置等待时间]。

         -线程传参

         -interrupt?????——应用场景?没见过

    【5】线程等待生命周期

         -获得锁,等待,释放资源(即释放锁);

         -被唤醒等待时间到,等待获取资源(获取锁),获取锁进入可执行状态

         -只能是同一个对象进行等待、唤醒

    【6】休眠

         -不可被唤醒,只能自己醒

         -休眠,阻塞,时间到,可执行状态执行

    【7】让步与优先级:threa.setPriority(1~10)

         -Thread.MAX_PRIORITY

         -Thread.MIN_PRIORITY

         -让步,可执行状态,执行。yield(),不能保障太多,基本不用。

    【8】合并

         -线程原本是并行的,合并后,线程变成串行。

         -合并的线程,可以在指定时间后,自动开始执行。

         -与sleep()机制一致:生命周期一致

         -线程start()后,才能 join()

    【9】守护线程

         -区别于【1-8的】用户线程

         -thread.setDaemon(true);——设置为守护线程

         -用户线程结束,守护线程立刻结束


    i++:分三步操作,不是原子性操作。{读、改、写}


    思考点:多线程读取三体多集,分别初步处理。然后合并,MR处理。

    0417——同步与锁

    多线程的问题:

    【1】对相同数据的并发操作:获取  查看  【修改   赋值】

    【2】但是无论多少线程并发,如果只是查看数据,那么该行为不会产生影响。

    ----synchronized——同步

    【3】线程同步:让某个方法在并发的情况下,依次排队执行。同一时刻,只有一个线程,拥有该方法或者代码块的锁,称:持锁。

    【4】Java中每个对象都有一个内置锁。

    【5】只能同步方法、代码块,不支持变量、类。

    -------同步锁的影响

    【1】同步锁会对多项成情况下的程序执行效率降低。

    【2】不存在类的同步、属性的同步。

    【3】sleep(),不会释放锁。

    【4】synchronized(this){【会受到并发影响的代码块通通包裹起来】} –同步代码块;读数据不受并发影响---保障同步代码块之外的其他数据不受影响!

    【5】同步代码块zhi前可以做一些具有共享的操作,或者不影响数据的操作:同步代码块之后的内容,会受到同步等待的影响。

    【6】同一段代码块,如果锁的对象不同,同步不生效。当且仅当锁同一个对象,并发生效。

    【7】一个线程可以同时持有多个对象的锁。同时拥有多个对象锁的情况下,有可能会产生死锁。虽然这个概率极低。——但是只要有这种可能性存在,那么就必须考虑周全!

    -----静态方法的同步

    【1】synchronized(A.class){}——同步是class

    【2】静态代码块的同步,A.test()_静态方法的同步

    con:

    【1】静态与非静态同步方法永远不会阻塞。

    【2】多项成同时访问互斥数据是,同步保护数组。

    【3】非静态、静态同步最好不要混用![减少嵌套]——主要原因是:很难控制,除非对底层及整个机制熟稔

    【4】即便是线程安全的类,在并发情况下,会受到其他变量或者非同步方法的影响,从而对数据安全造成隐患。——操作线程安全类的逻辑本身不安全。——通过对整个操作逻辑进行加锁实现安全。

    【5】原子化操作。

    -------volatile

    【1】可见性:确保释放锁之前对共享数据做出的更改,对于随后获得该锁的另一个线程是可见的。

    【2】Volatile:不能保障数据安全。

    【3】实现数据安全:1,把读和写分开。

    【4】volatile 不能用于 final对象。

    【5】JavaBean当中,属性可以加Volatile修饰,然后给set方法加同步。

    -------可见性适合一个线程写,多个线程读项目中单例我就加了volatile


    excludes:

    缓存(cache)是在读取硬盘中的数据时,把最常用的数据保存在内存的缓存区中,再次读取该数据时,就不去硬盘中读取了,而在缓存中读取。
    缓冲(buffer)是在向硬盘写入数据时,先把数据放入缓冲区,然后再一起向硬盘写入,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。
    简单来说,缓存(cache)是用来加速数据从硬盘中"读取"的,而缓冲(buffer)是用来加速数据"写入"硬盘的。

    =============

    Scanner next()&&nextLine()方法区别

          -Scanner是一个扫描器,我们录取到键盘的数据,先存到缓存区等待读取,它判断读取结束的标示是  空白符;比如空格,回车,tab 等等。

          -next()方法读取到空白符就结束l;

          -nextLine()读取到回车结束也就是“ ”;

  • 相关阅读:
    lufylegend:图形变形3
    javascript: Math.sin() cos() 用法
    lufylegend:图形变形2
    lufylegend:图形变形1
    lufylegend:图片的加载和显示
    lufylegend基础知识1
    canvas使用3
    canvas使用2
    canvas使用1
    javascript:addEventListener
  • 原文地址:https://www.cnblogs.com/macro-renzhansheng/p/12722737.html
Copyright © 2020-2023  润新知