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()读取到回车结束也就是“\r”;

posted @ 2020-04-17 21:57  小海_macro  阅读(231)  评论(0编辑  收藏  举报