美文网首页
黑马--多线程

黑马--多线程

作者: 资深菜鸡程序员 | 来源:发表于2021-05-12 21:35 被阅读0次

    1.FutureTask示例代码

                  FutureTask的get方法是一个阻塞方法,需要等线程代码执行完毕才会接着执行。

                     FutureTask的 cancel(boolean mayInterruptIfRunning) 方法是中断线程执行的方法,传入false表示不允许中断正在执行的线程,true则表示允许中断。

                     isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。

                     isDone方法表示任务是否已经完成,若任务完成,则返回true;

                     get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。


    2.查看线程的方法

         windows下: JDK提供的查看java线程的方法jps,杀死进程的方法taskkill /F /PID xxxx

    3.线程上下文切换的原因

    4.睡眠的线程被唤醒 

       4.1调用线程的interrupt()方法 如图4-1,

       4.2此方法还会打断正在执行的线程,如图4-2。

       4.3根据interrupt方法的两阶段终止设计模式如图4-3,因为在执行sleep的时候会清除终止标记所以在catch中重新标记清楚状态为true

       4.4 interrupt会影响park方法的执行如图4-4

                                                                                                   图4-1,

                                                                                                          图4-2

                                                                                        图4-3

                                                                                                                 图4-4  

    5.线程睡眠的方法尽量替换成  TimeUnit.SECONDS.sleep(1); 这种方式可读性高一点

    6.yield方法

    (1).是会把当前调用此方法的线程执行权交出去,会把当前线程从运行状态变成就绪状态。

    (2).还是要根据操作系统的调度器来实现,有可能交出去执行权后cup此时比较空闲,那当前线程有可能接着拿到执行权,接着执行。

    7.join()方法 等待线程运行结束  主线程等待t1线程运行结束   join(long xxx)方法是限时等待

    8.守护线程在主线程结束运行后,也会随之结束运行。

    9.线程的状态(java层面是6种状态)

          新建,运行,停止,如果线程 调用seelp方法他的状态是 timed waiting ,调用join方法状态是 waiting,竞争锁失败处于阻塞状态是blocked

          情况2是 调用了wait方法,会进入Monuitor中的WaitSet集合等待,当调用notify或notifyAll时,线程会进入EntrySet集合进行竞争资源,竞争成功则进入运行状态,失败则是状态9BLOCKED

    10.线程安全分析

       10.1 局部变量不会存在线程安全问题,因为不同线程调用方法都会创建不同的栈帧不存在数据共享问题,

      10.2 方法内引用全局变量也会存在线程安全问题,因为不同线程使用的是同一个值。

    10.3 引用暴漏 在子类上覆盖父类方法也可能会出现线程安全问题。

    11.常见线程安全类

    12.偏向锁:

         偏向状态:

              Biased就是偏向状态:默认是开启了偏向锁,但是会有延迟如图 12-1   01代表是无锁状态,4秒后打印出结果已经开启了偏向锁结果是101

              如图 12-2  添加了参数 -XX:BiasedLockingStartupDelay=0 关闭延迟开启偏向锁,在同步代码块中将线程id写入对象头,在同步代码结束后对象头中依然存在线程id说明当前锁偏向这个id线程。

              如图12-3禁用偏向锁参数 -XX:+UseBiasedLocking 此时就会直接从无锁状态升级成轻量级锁。

              如图12-4调用对象的hashcode方法就会把偏向的锁退回到无锁状态,因为状态为偏向锁的对象头中没有足够的空间存储hashcode,轻量级锁和重量级锁就不会,因为轻量级锁的hash码会存在栈内存的所记录里,重量级锁会存在Monuitor对象中,解锁的时候会还原回来。

              如图12-5偏向锁的撤销,其实就是升级到了轻量级锁,这段代码演示了升级到轻量级锁的过程。

              如图12-6批量撤销20次:集合中的对象已经偏向t1了,此时让他批量撤销偏向的操作,偏向到第20回时线程将不会再升级,jvm会进行优化,会让之后的对象都偏向与t2线程不再进行偏向撤销。

              如图 12-7批量撤销操作40次:JVM就会觉得自已确实错了,就不该批量偏向,40次之后的默认对象将不再是偏向状态,而是不可偏向状态。

                                                                                图 12-1 

                                                                                      图 12-2

                                                                                   图 12-3

                                                                              图12-4

                                                                                    图12-5

                                                                                    如图15-6

    13.wait/notify

              13.1 如图13-1 使用起来注意,如果使用notifyAll的时候要避免虚假唤醒,如果唤醒的不是当前线程,可以使用while循环的方式让其当前线程再次进行等待。

                                                                                   图13-1

               原理:

    13.2  利用wait/notify 设计 保护暂停模式,该模式的特点就是一对一的生产和消费,

               代码gitee地址:https://gitee.com/achivedream/brief-book-code/blob/master/%E4%BF%9D%E6%8A%A4%E6%9A%82%E5%81%9C%E6%A8%A1%E5%BC%8F

    13.3 利用 wait/notify 设计生产者消费者模式,该模式的特点不是一对一的生产和消费,而是多对多,只要生产出了产品消费者竞争到资源就可以进行消费

                 代码gitee地址:https://gitee.com/achivedream/brief-book-code/blob/master/%E7%94%9F%E4%BA%A7%E8%80%85%E6%B6%88%E8%B4%B9%E8%80%85%E6%A8%A1%E5%BC%8F

    14.park和unpark

             park方法会让线程在执行中进入等待,unpark可以将执行了park方法的线程唤醒,他的特点是不管在park方法执行前后都可以唤醒线程。如图14-1

                                                                              图14-1

          特点:

    15.死锁(活跃性)

                代码演示:

        15.1.查看死锁的工具   打开IDEA Terminal控制台

            1.jps查看java相关的线程,再用 jstack 259592 查看线程状态,jvm会自己发现死锁,并给出提示

               JVM死锁提示:

                2.用jconsole工具来进行查看线程死锁状态。

    15.ReentrantLock S

              15.1可打断锁是防止其他线程一直未获取到锁

    相关文章

      网友评论

          本文标题:黑马--多线程

          本文链接:https://www.haomeiwen.com/subject/uhlwdltx.html