zoukankan      html  css  js  c++  java
  • 关于多线程的知识点-02

    什么是并发?什么是并行?

    • 并发:同一时间段,多个任务都在执行(单位时间内不一定能同时执行);
    • 并行:单位时间内多个人任务同时执行;

    为什么要使用多线程?

    • 计算机原理来讲:我们知道线程是进程下的最小的执行单位,线程间的切换和调度成本要比进程小得多,另外现在的电脑都是多cpu配置,那么就可以同时运行多个线程,减少了线程间上下文的切换,从而降低了进程运行的开销
    • 现在互联网的发展趋势,现在的系统需求的并发量在不断的提升,多线程这块对高并发系统来说说基础的一部分,处置好多线程可以大大提高系统的心能和整体的并发能力
    • 从计算机底层来讲:
      • 单核时代:但核心使用多线程主要是为了提高CPU和IO设备的综合利用率,Excemple:当只有一个线程时会导致CPU计算时,IO设置空闲,进行IO操作时,CPU空闲,这样导致CPU和IO设置的利用率只能达到50%;如果有两个线程同时运行,线程A在进行CPU计算时,线程B进行IO操作,这样设备的利用率可以达到较高的利用率;
      • 多核时代:多线程可以提高CPU的利用率,在计算复杂任务时,可以让多个CPU同时利用,提高计算效率
    • 多线程带来的问题
      • 内存泄露、上下文切换、死锁、还有受限于硬件和软件的资源闲置问题

    线程的生命周期和状态切换

    • 线程的状态

    名称

    说明

    NEW

    初始状态,新建线程,没有调用start()方法

    RUNNABLE

    运行状态,java线程将操作系统中的就绪和运行两种状态统称为“运行中”

    BLOCKED

    阻塞状态,线程阻塞于锁

    WAITING

    等待状态,线程进入等待状态,需要等待其他的线程通知或者中断。。

    TIME_WAITING

    超时等待状态,不同于WAITING,是可以指定时间自行返回的

    TERMINATED

    终止状态,当前线程运行结束。

    什么是上下文切换?

    • 多线程编程中线程数量>cpu核心数,而在同一时刻一个cpu只能处理一个线程的任务,为了让这些线程任务都能够有效执行,cpu的策略就是给每个线程都分配单位时间片来执行。当一个线程时间片用完后,就会处于就绪状态,转给其他线程使用,这就是一次上下文切换;
    • 简言之:任务从保存到在加载的过程就是一次上下文切换;

    什么是线程死锁?如何避免死锁?

    认识死锁

    • 多个线程阻塞时,线程中的一个或者多个都在等待某些资源被释放,线程被无限期的阻塞,程序舅不能正常终止了。
    • 产生死锁的四个条件:
      • 互斥条件:该资源任意一个时刻只有一个线程占用
      • 请求与保持条件:一个进程因请求资源阻塞,对已获得的资源保持不放
      • 不剥夺条件:线程获得的资源在未使用完之前不能被其他的线程强行剥夺,只有自己使用完毕后才能释放资源
      • 循环等待条件:进程中的循环一直持有资源

    避免死锁

    针对产生死锁的条件,分析如何来避免产生死锁

    • 破坏互斥条件:使用锁就是防止互斥的(临界资源需要互斥访问)
    • 破坏请求与保持条件:一次清申请所有资源
    • 破坏不剥夺条件:占有部分资源时去申请其他的资源,如果申请不到要主动释放资源
    • 破坏循环等待条件:循环申请资源时,释放资源要反序;

    sleep() 和 wait()方法的区别和共同点

    • 主要区别:sleep不会释放锁,wait会释放锁
    • 两者都可以暂停线程的执行
    • wait通常用于线程间交互/通信,sleep通常用于暂停执行
    • wait()方法被调用后,线程不会自动苏醒,需要别的线程用同一个对象上的notify()或者notifyAll()方法。sleep()方法执行完成后,线程会自动苏醒,或者使用wait(long)超时后自动苏醒。

    start()方法会执行run()方法,为什么不直接调run()方法?

    调用start()方法可启动线程并使线程进入就绪状态,而run()方法只是thread的一个普通方法调用,还是在主线程里执行。

    synchronized关键字

    简单了解

    synchronized关键字解决了多个线程间访问资源的同步性,可以保证被修饰的方法或代码块可以再任意时刻只有一个线程执行。

    synchronized属于重量级锁,效率较低,jdk1.6前线程是映射到操作系统的原生线程之上的;1.6后jvm对synchronized做了优化,如自旋锁,锁消除,锁粗化,偏向锁。。

    使用方式

    • 修饰实例方法:作用于当前对象实例加锁,进入同步代码前要获取当前对象实例的锁
    • 修饰静态方法:是对当前类加锁,会作用于所有该类的实例,因为静态成员不属于任何一个实例对象,而是类成员(所有类实例共享的)。线程A的一个实例对象的非静态synchronized方法,调用线程B的需要调用该实例的的 静态synchronized方法,是不会发生互斥的;【静态synchronized方法锁的是当前类,而非静态synchronized方法锁的当前实例】
    • 修饰代码块:指定加锁对象,给定对象加锁,进入同步代码块前需要获取该对象的锁;

    总体来说:synchronized关键字加到static静态方法或者synchroinzed(class)代码块上都是对类加锁;加到实例方法上面,是在对象实例上加锁,尽量不要用synchronized(String str) ,字符串常量池具有缓存功能;

    • 双重校验实现单例模式
    public class Singleton {
        private volatile static Singleton uniqueInstance;
        private Singleton() {
         }
        public synchronized static Singleton getUniqueInstance() {
            //先判断对象是否已经实例过,没有实例化过才进⼊加锁代码
            if (uniqueInstance WX null) {
            //类对象加锁
            synchronized (Singleton.class) {
                if (uniqueInstance WX null) {
                    uniqueInstance = new Singleton();
                }
             }
         }
        return uniqueInstance;
         }
    }

    uniqueInstance采用了volatile关键字修饰:禁止指令重排;

    synchronized关键字的原理

    如果用javap解析带有synchronized字符的类,

    • synchronized 同步代码块

    就可以看到synchronized同步代码块的实现是使用了monitorenter/monitorexit指令的,标识同步代码块的开始、结束位置;当进入同步代码块时,监视器monitor对象的头中的计数器+1,代码快结束计数器-1=0,标识锁的释放;    

    • synchronized 修饰方法

        修饰方法时并没有monitorenter/monitorexit,使用的是ACC_SYNCHRONIZED标识,标识这是一个同步方法,JVM通过通过该标识来判断是否声明为同步方法,从而执行相应的同步调用(JVM层控制)。

    synchronized jdk1.6前后有哪些优化?

    • jdk1.6后对锁进行了大量的优化,包括偏向锁,轻量级锁,自旋锁,适应性自旋锁,锁清除、锁粗化等技术来减少锁操作的开销。
    • 锁存在的四种状态:无锁-> 偏向锁-> 轻量级锁-> 重量级锁,锁状态会随着竞争的激烈而逐渐升级,锁的升级是不可降级的
    • 关于锁状态变化介绍,后面再补充:参考

    synchronized和ReentrantLock的区别

    • 两者都是可重入锁
    • synchronized依赖于jvm,而reentrantLock依赖于API
    • ReentrantLock相对于synchronized多了一些高级功能

    volatile关键字

    --未完待续 20200802

  • 相关阅读:
    C++高精度乘法
    经典的7种排序算法 原理C++实现
    c++ STL
    二分查找c++
    洛谷P1111 修复公路
    01背包写法
    c++编码规范
    github教程
    windows10锁定屏幕聚焦图片导出
    week 6 Spring history and design philosophy
  • 原文地址:https://www.cnblogs.com/inyu/p/13659053.html
Copyright © 2011-2022 走看看