【java多线程】java多线程编程核心技术1-2章——读书笔记

学习多线程并发,要着重“外练互斥,内修可见”

第一章:

     基础知识,基本方法介绍及实例使用

 

第二章:

    同步、锁:锁的是同一个对象、同步,不同的对象、异步

    锁:

         1、可重入锁:自己可以再次获取自己的内部锁,支持父子环境

         2、出现异常,锁自动释放

 

   synchronized:

          1、synchronized(this)锁定当前对象

          2、线程访问object的一个同步代码块时,其他线程对该object中其他的synchronized(this)同步代码块的访问将被阻塞,synchronized使用的“对象监视器”是一个:同步、阻塞

          3、synchronized(非this的对象x),将x作为对象监视器

                  1 多个线程同时执行synchronized(x){}呈同步效果

                  2 其他线程执行x对象中synchronized同步方法时同步

                  3 其他线程执行x对象方法里面synchronized(this)代码块同步

                    其他线程调用不加synchronized关键字方法,还是异步调用

          4、静态同步:对当前*.java文件对应的class类进行持锁,给class类上锁,对所有对象实例起作用

          5、String类型的常量池缓存功能使得,相同的String相同的锁

    volatile:

             变量(读时)在多个线程间可见(从共享内存中读取变量),不支持原子性、同步性

           1、线程同步的轻量级实现,性能较synchronized好,只能修饰变量,而synchronized可修饰方法、代码块、保证原子性、简介保证可见性(私有、共有内存数据同步)

            volation解决变量在多个线程间可见性,synchronized解决多个线程间访问资源的同步性

 

第三章:线程间通信

     等待/通知机制:

       wait使线程停止运行,notify使停止的线程继续运行

       等待wait()当前执行代码的线程进行等待队列、释放被同步对象的锁,Object类的方法

             调用wait前须获得该对象的对象级别锁(只能在同步方法或同步块中调用wait方法)

             将当前线程置入“预执行队列”,在wait()所在代码行 处停止执行,直到接到通知或被中断为止

             执行wait方法后,当前线程释放锁,在从wait返回前,线程与其他线程竞争重新获得锁,如果调用时没有持有适当的锁则抛出IllegalMonitorStateException(runtimeException子类,不需要try-catch捕捉)

   

        notify()同步方法/块中调用,调用前必须获得对象的对象级别锁,否抛IllegalMonitorStateException

            通知哪些可能等待该对象的对象锁的其他线程,如有多个、由线程规划器挑选其中一个呈wait状态的线程,对其发出notify使其等待获取该对象的对象锁(唤醒线程(一个因wait而处于阻塞状态的线程)并使进入就绪可运行状态

            执行notify方法后,当前线程不会马上释放该对象锁,要等到执行notify方法的线程将程序执行完(退出synchronized代码块后)才释放锁,呈wait状态的线程才可获取该对象锁

             notifyAll所有正在等待队列等待同一共享资源的“全部”线程从等待状态退出,进入可运行状态,优先级

线程状态切换示意图:

     

1、新创建一个新的线程对象后,在调用其start(),系统将为此线程分配CPU资源,使其处于Runnable(可运行)状态:准备运行的阶段,如果线程抢占到了CPU资源,此线程就处于Running(运行)状态

2、Runnable状态和Running可互相切换,因为有可能线程运行一段时间后,有其他高优先级的线程抢占了CPU资源,此时此线程就从Running变成Runnable

     线程进入Runnable大致分为如下5种情况:

         1.调用sleep方法后经过的时间超过了指定的休眠时间

          2.线程调用的阻塞IO已经返回,阻塞方法执行完毕

         3.线程成功获得了试图同步的监视器

         4.线程正在等待某个通知,其他线程发出了通知

         5.处于挂起状态的线程调用了resume恢复了方法

3、Blocked是阻塞的意思,如遇到一个IO操作,此时CPU处于空闲状态,可能会转而把CPU时间片分给其他线程,这是也可以称为“暂停”状态;Blocked状态结束后进入Runnable,等待系统重新分配资源

     出现阻塞情况大体分为如下5种情况:

           1.线程调用sleep,主动放弃占用的处理器资源

           2.线程调用阻塞IO方法,在该方法返回前,该线程被阻塞

           3.线程视图获得一个同步监视器,但该同步监视器正被其他线程所持有

           4.线程等待某个通知

           5.程序调用了suspend方法将该线程挂起,此方法容易导致死锁,尽量避免使用该方法

4、run方法运行结束后进入销毁阶段,这个线程执行完毕

每个锁对象有两个队列,一个就绪、一个阻塞,就绪存储将要获得锁的线程,阻塞存储被阻塞的线程,一个线程被唤醒后才会进入就绪队列,等待CPU调用,反之一个线程被wait后就会进入阻塞队列,等待下一次被唤醒

  3.1.10等待wait条件发生变化——实验与书中结果不符??线程一直在等待,锁住的是同一个对象lock,改成while也是死锁

线程组:ThreadGroup是java.lang的内容,不属于java并发包

     线程组ThreadGroup:一组线程的集合,一旦一个线程归属到一个线程组后,便不能更换其所在的线程组

     好处:方便同一管理,组可以复制,快速定位到一个线程,统一异常设置

     方法:

          1、获取当前线程名:Thread.currentThread().getThreadGroup().getName()

          2、将线程放入组中:构造函数

          ……见以后博客

猜你喜欢

转载自blog.csdn.net/ma15732625261/article/details/81166940