• 并发编程之线程


    一、创建线程的方式

    1.继承Thread类,重写该类的run()方法。

    2.实现Runnable接口,并重写该接口的run()方法,该run()方法同样是线程执行体,创建Runnable实现类的实例,并以此实例作为Thread类的target来创建Thread对象,该Thread对象才是真正的线程对象。接口 静态代理

    3.使用Callable和Future接口创建线程。具体是创建Callable接口的实现类,并实现call()方法。并使用FutureTask类来包装Callable实现类的对象,且以此FutureTask对象作为Thread对象的target来创建线程。有返回值和异常。JUC包

     二、线程的生命周期及五种基本状态

      2.1 线程生命周期:新建(new)、就绪(start/yield等)、运行(CPU run)、阻塞(sleep/join等)、死亡(stop/加flag)。

     2.2 Thread类和Object的方法

    sleep暂停/yield礼让属于类方法;join插队属于对象方法。

      2.3 守护线程

        用户线程和守护线程(Daemon)。jvm的退出不用等待守护线程执行完成。例:垃圾回收线程。应用场景:jvm退出时,线程能够自动退出。

        设置守护线程:t.setDaemon(true)  验证守护线程:t.isDaemon.

      2.4 Hook(钩子)线程 

        jvm退出的时候,钩子线程就会被启动执行。

       Runtime.getRuntime().addShutdownHook(new CleanWorkThread());

      2.5 常用方法

      isAlive()、setName()、getName()、currentThread()类方法。

    三、高并发

     3.1 并发:同一个对象多个线程同时操作。抢占资源

     3.2 线程同步(线程安全):队列与锁 Synchronized

     锁机制:锁住对象或Class对象。

     3.3 Synchronized方法和Synchronized块 线程安全

         synchronized 方法:public synchronized void test(){}。

      synchronized 块:synchronized (obj){}。 obj:同步监视器。粒度更小

           性能优化:临界值、double checking。

      3.4 并发容器

          concurrent包:CopyOnWriteArrayList

      3.5 死锁

          原因:相互不释放资源。

          避免:不要在同一个代码块中,同时持有多个对象锁。

     3.6 并发协作 线程协作

          3.6.1生产者消费者模式

           1) 线程通信

          3.6.2协作模型之管程法

            1)生产者 消费者 缓冲区

            2)Object类  wait() 释放锁,notify()/notifyall() 成对出现

          3.6.3协作模型之信号灯法

           1)生产者 消费者 标志位

     3.6 高级主题-定时调度

      java.util.Timer

           java.util.TimerTask

     3.7 任务定时调度框架-quartz

         Scheduler:调度器,控制所有的调度

         Trigger:触发条件,采用DSL模式

         JobDetail:需要处理的任务

       Job:执行逻辑

     3.8 重排序:Happen-Before

        重排序:编译器和CPU会尝试重排指令使得代码更快地允许。目前:提供性能

        数据依赖:编译器和处理器在重排序时,会遵守数据依赖性,编译器和处理器不会改变存在数据依赖关系的两个操作的执行顺序。

    3.9 volatile修饰

        当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,

        当有其他线程需要读取时,它会去内存中读取新值(JMM通过将工作内存的设为失效,以让其直接去读内存)。

        volatile变量的内存可见性是基于内存屏障实现的。

       1) java内存模型中的可见性、原子性和有序性。

           可见性:是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。Java中volatile、synchronized和final实现可见性。

      原子性:synchronized、lock、unlock保证原子性。

           有序性:volatile、synchronized保证线程之间操作的有序性。

       2) volatile保证线程间变量的可见性。不能保证原子性。

       3) 原理:内存屏障。通过内存屏障可以禁止特定类型处理器的重排序。

      4) volatile规则:如果一个线程对volatile变量读,另一个线程对该变量写,那么写操作一定发生在读操作之前。

    3.10 dcl单例模式

        volatile保证线程间变量的可见性。不能保证原子性。

        1)构造器私有化-->避免外部new构造器

        2)提供私有的静态属性-->存储对象的地址

        3)提供公共的静态方法-->获取属性

    3.11 ThreadLocal 线程的本地存储区域

        get/set/initialValue初始化方法。

        private static修饰

        InheritableThreadLocal:继承上下文环境的数据,拷贝一份给子线程。

    3.12 可重入锁实现原理

        锁可以延续使用+计数器

        可重入锁:公平锁和不公平锁。公平锁:等待时间长的先获得锁。

        JUC包:ReentrantLock.

    3.13 CAS原子操作 Compare and swap 比较并交换。

       悲观锁:synchronized关键字、lock接口。

       乐观锁:CAS:属于硬件级的操作(利用CPU的CAS指令),是乐观锁的一种实现。效率高

      JUC(java.util.concurrent)中AtomicXxx类:AtomicInteger.decrementAndGet()。

    四、多线程小结

     4.1 推导lambda简化线程    拉姆达

     4.2 在并发编程中,比较常用的是使用synchronized关键字和Lock接口同步,或者volatile关键字,来确保多线程下的有序性。

       

  • 相关阅读:
    MySQL命令行基本操作
    MYSQL多表查询笔记
    MYSQL事务笔记
    Linux测试环境部署相关命令和步骤
    Jmeter录制脚本
    办公软件通讯录排序相关测试点
    Burp Suite抓包App
    安全测试 Burp Suite抓包工具
    及时通信办公软件,验证码登录,获取验证码失败原因分析和规避方法
    redis内存溢出问题分析和后续规避方法
  • 原文地址:https://www.cnblogs.com/wenxiangchen/p/10955879.html
Copyright © 2020-2023  润新知