zoukankan      html  css  js  c++  java
  • 多线程基础

    学习资料:

     深入浅出多线程     JavaGuide 《并发编程的艺术》  百度233

    1,进程与线程

    1.1,进程:运行一个程序,就会创建进程。应用程序在内存中分配的空间。让操作系统实现并发。

            线程:一个程序(进程)的子任务。实现进程内部的并发。轻量级线程。

    1.2,关系:

    has a     进程可以包含多个线程,共享进程的资源。

    is   a      线程是轻量级的进程

     

    2,并发与并行:

    并发:同一时间段内,多个任务都在指行(单CPU进程调度)看起来是并行的。

    并行:同一时刻,多个任务同时执行,(多核CPU,真正意义上的并行)

    3,为什么使用多线程

    消耗资源小。线程切换和调度的成本远小于进程,

    相应速度快。大量并发网络环境,需要多线程机制快速相应。

    • 多线程应用场景:Web服务器,专用服务器(游戏)。后台任务(群发邮件)。异步处理。分布式计算。

    CPU利用率高。多核CPU时代,多个核心运行多个线程,减少饥饿。

    • 线程越多,利用率就越高?  多线程一定能提高CPU利用率?     

    使用多线程之前CPU的空闲时间  大于  使用多线程后用于线程切换上下文的时间。两者之差才是提升CPU真正利用在计算上的时间。

    • 什么是上下文切换

    线程/进程 调度 中时间片流转法,当一个线程时间片用完或者被中断阻塞了,要切换下一个就绪队列中的线程,要保存当前线程的‘现场’

    ,即线程状态信息,资源信息,程序计数器(记住线程执行到哪了,下次轮到时间片时接着执行)等。同时将要切换进来的线程保存的

    ‘现场’信息加载进来,接着他上次执行的地方接着执行。

    4,线程的生命周期:NEW ,RUNNABLE,BLOCED,WAITING,TIME_WAITING,TERMINATED

    ①new一个线程的时候,处于NEW状态

    ②调用start之后处于RUNNABKE状态,可执行态,分为就绪态(等待CPU时间片)和运行态。

    ③BLOCED:当线程尝试获取锁失败被挂起阻塞时

    ④WAITING,Object.wait(),Thread.join(),后释放cpu和锁,等待被唤醒。Object.notify(),Object.notifyAll().

    ⑤TIME_WAITING,超时等待(定时等待)一定时间后回到可执行态。Thread.join(long),Object.wait(long),Thread.sleep(long)

    ⑥TERMINATED,线程run方法执行完成后。

     

    5,创建多线程方法

    继承Thread类,实现Runnable接口,实现Callable接口(有返回函数)

     

    6,多线程带来的问题:

    死锁,内存泄漏,线程不安全(数据不同步),

    。。。

     

    7,解决多线程同步问题:

    既然多线程同一时刻有多个线程访问/修改同一个资源/数据,会出错。那就把资源/数据 锁住就像公共厕所,入坑关门反锁,排队(抢锁机制)入坑。

    7.1,锁。    synchronized与Lock

    锁分类:(不可不说的Java“锁”事

    可重入锁-非可重入锁 , 公平锁-非公平锁 ,  读写锁-排他锁 , 悲观锁-乐观锁。

    常用排他锁:synchronized  ,Reentrantlock

     

    7.2,锁的结构:(个人理解,如有误导,多谢指正)

    ①锁状态(锁标识,)

                标识位,一般用一个volatile  int遍量 如   private volatile int state;(volatile后面再解释),规定好,state的值为多少对应什么状态

              上锁释放锁时对state怎么操作(+1,-1)

    ②阻塞队列+排队机制(抢锁机制根据锁状态)

     

    ③等待/通知机制(释放锁的时候通知其他人现在锁空了,赶紧来枪锁)(这是线程之间通信里的内容,放锁里一起理解,便于比较)

     

    8,CAS操作:

    CAS的全称是:比较并交换(Compare And Swap)。在CAS中,有这样三个值:

      • V:要更新的变量(var)
      • E:预期值(expected)
      • N:新值(new)

    比较并交换的过程如下:

    判断V是否等于E,如果等于,将V的值设置为N;如果不等,说明已经有其它线程更新了V,则当前线程放弃更新,什么都不做。

    所以这里的预期值E本质上指的是“旧值”。

    我们以一个简单的例子来解释这个过程:

      1. 如果有一个多个线程共享的变量i原本等于5,我现在在线程A中,想把它设置为新的值6;
      2. 我们使用CAS来做这个事情;
      3. 首先我们用i去与5对比,发现它等于5,说明没有被其它线程改过,那我就把它设置为新的值6,此次CAS成功,i的值被设置成了6;
      4. 如果不等于5,说明i被其它线程改过了(比如现在i的值为2),那么我就什么也不做,此次CAS失败,i的值仍然为2。

    在这个例子中,i就是V,5就是E,6就是N。

    那有没有可能我在判断了i为5之后,正准备更新它的新值的时候,被其它线程更改了i的值呢?

    不会的。因为CAS是一种原子操作,它是一种系统原语,是一条CPU的原子指令,从CPU层面保证它的原子性

    当多个线程同时使用CAS操作一个变量时,只有一个会胜出,并成功更新,其余均会失败,但失败的线程并不会被挂起,仅是被告知失败,并且允许再次尝试,当然也允许失败的线程放弃操作

     

  • 相关阅读:
    正则表达式基础
    js正则:零宽断言
    IE读取并显示本地图像文件的方法
    转:FileReader详解与实例---读取并显示图像文件
    mysql基础(mysql数据库导入到处) 很基础很实用
    如何禁止页面滚动
    转:字符编码到底是怎样的 有空看
    自己写的一个简单的Tab类
    mysql学习总结
    mysqld守护进程
  • 原文地址:https://www.cnblogs.com/wangpan8721/p/13782620.html
Copyright © 2011-2022 走看看