zoukankan      html  css  js  c++  java
  • 温故知新 线程

    项目中常会用到定时器任务调度(线程知识)

    本人原电子系后转行到软件,所以对计算机原理方面颇感兴趣!

    谈线程钱必须知道进程,CPU调用程序,以进程体系,轮询。

    时间片(CPU定轮询周期),每个进程周期一样,(如上图)当前执行进程1指令。执行到一半,操作系统OS (管理计算机硬件与软件资源的计算机程序,同时也是计算机系统的内核与基石给它分配时间到了,收回。

    它把这个进程挂起,暂时保存起来。OS就去按顺序遍历,执行进程2,...........直到执行到进程8的时间片用完了,挂起进程8接着执行进程1,恢复现场,接着执行。

     

     

    注意:进程调度,程序之间可以切换cpu执行太快会给人错觉误以为程序都是并行(同时运行);其实cpu定轮询周期(时间片),每个进程运行/执行的时间固定,当时间到了进程仍没执行完,当前进程挂起,执行下一条进程(直到进程8结束),当OS再次执行时,又回到进程1,恢复现场,接着执行;

    知道了进程后,开始谈谈线程了:

    一个进程可包含多个线程,也就是线程是OS(操作系统)可以执行的最小单位;(查服务器主机几核几线程  【cmd->wmic->cpu get *】查看对应的NumberOfCoresNumberOfLogicalProcessors

    线程数=Ncpu/(1-阻塞系数)

    Ncpu---CPU数     阻尼系数---(0到1之间)

    线程数大于CPU核数(并行):

    并行多核情况下各自CPU执行各自内容,可以同时执行;

    并发多核情况下,某一个核中执行个线程,此时就产生并发,分片执行,轮着顺序执行。也称为交替执行。

    上图摘自网络:(一图胜千文)

    JVM在多线程时,访问公用变量(堆、方法区。。。)的每个线程是自由的,但有线程存在私有变量会有私有的栈来供他存放(保证了线程间隔离的安全)

    切记创建线程数非常多,可能造成内存溢出;--------因为每个线程要分配单独内存空间,直接占用。(可以理解为独食大王,宁占着不让位)

     

    多线程创建方式:

    1) 继承Thread

    2) 实现Runnable,无返回值,无异常接收

    3) 实现Callable,返回值,接收异常,多了一些对象 FutureFutureTask

    4) 线程池

    多线程状态:

    1,新建new;调用start()方法,注:所有的线程都从start开始(仅一次且由OS决定

    2,可运行态Runnable; 1, 当时间片用完,运行态会调用 yiled()转到可运行态;注:【yiled() 会强制退回到就绪状态,代码主动调用。主动把CPU让出来,让其他线程去执行。俗称挂起   ,2,当OS选中时,会从可运行态转运行态;

    3,运行态Running;Run方法执行完成,线程就结束,释放资源。(切记不要本线程调用---那将毫无意义)

    4,阻塞态blocked;  对于阻塞态运行态可运行态 典型的稳定三角关系:

    运行态变阻塞:

            sleep()   【它会把CPU让出来,先阻塞等待(我先睡会你们继续)】醒来后转为可运行态;

            join() 【运行快的所有线程都等待,只到最慢那个线程执行完成,(有福同享,有难共当)】   

            wait()   【当前线程优先占用,其他线程停止,(有肉我先吃)】 当调用interrupt()或notify()或notifyAll()被唤醒后仍处于阻塞态,可转为可运行态;’

            加锁Synchronized 【关键字,同步,同步锁,代码块,多行代码被加锁】 原子性操作,其他线程无法执行(特别注意CPU不是立即执行,而是轮询到它在执行。),切记加锁范围越小越好!

    阻塞态变可运行态:获得锁   sleep时间到了

    5,终止态Dead ;run()结束

     

    特别要重视线程池:

    通俗讲就是线程的集合,一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。(可以理解为 孟尝君食客三千待用);

    作用:防止多线程运行,系统不断闭合新线程,系统资源不断消耗,线程切换频繁,导致系统崩溃 (蓝屏的真好喝!)

    线程池可参见博客大神闯天创世纪的博文:https://www.cnblogs.com/jiawen010/p/11855768.html

     

    多线程并发在项目中常见安全问题:

    甩卖问题:

    多个窗口卖固定的货:      m个窗口   卖n件货

    线程m个   甩卖过程   n递减(假设没退换,卖出责任不究)

    其实主要是当n=1时问题出来了,要解决超卖现象:解决办法-------加锁(执行结束锁就释放),在加锁范围内不能高并发,只能一个对象去使用。

     

    在商品秒杀系统时,有条件有选择的在读操作上加锁,库存小于一个量时开始加锁,让购买者排队;用一个队列缓存,将多线程变为单线程读写;

     

     

     

     

     

     

  • 相关阅读:
    android Fragment和FragmentActivity
    android 生成xml文件
    android:在ViewPager中使用Button
    android延迟执行
    android.os.NetworkOnMainThreadException 异常
    导入android工程没有R文件的解决办法
    20个常用的Java程序块
    Java中的==、equals、hasCode方法
    《head first java 》读书笔记
    【写给自己】2014-03-13
  • 原文地址:https://www.cnblogs.com/pureray-hui/p/12560513.html
Copyright © 2011-2022 走看看