day20—线程通信:等待唤醒机制

2 篇文章 0 订阅
  1. 线程通信:线程之间需要协作必须能够通信
  2. 问题1:出现姓别紊乱的情况.
                     解决方案:只要保证在生产/消费姓名和性别的过程保持同步,中间不能被消费者线程进来取走数据.
                     可以使用同步代码块/同步方法/Lock机制来保持同步性.
        问题2:应该出现生产一个数据,消费一个数据.
                     应该交替出现:  春哥哥-男-->凤姐-女-->春哥哥-男-->凤姐-女
                     解决方案: 使用 等待和唤醒机制.
  3. 当前生产者在生产数据的时候(先拥有同步锁),消费者获取不到锁,不能执行popup

  4. 线程通信-wait和notify方法介绍:
    wait():执行该方法的线程对象释放同步锁,JVM把该线程存放到等待池中,等待其他的线程唤醒该线程.
    notify:执行该方法的线程唤醒在等待池中等待的任意一个线程,把线程转到锁池中等待.
    notifyAll():执行该方法的线程唤醒在等待池中等待的所有的线程,把线程转到锁池中等待.
    注意:上述方法只能被同步监听锁对象来调用,否则报错IllegalMonitorStateException..
    ------------------------------------------
    假设A线程和B线程共同操作一个X对象(同步锁),A,B线程可以通过X对象的wait和notify方法来进行通信,流程如下:
    1:当A线程执行X对象的同步方法时,A线程持有X对象的锁,B线程没有执行机会,B线程在X对象的锁池中等待.
    2:A线程在同步方法中执行X.wait()方法时,A线程释放X对象的锁,进入A线程进入X对象的等待池中.
    3:在X对象的锁池中等待锁的B线程获取X对象的锁,执行X的另一个同步方法.
    4:B线程在同步方法中执行X.notify()方法时,JVM把A线程从X对象的等待池中移动到X对象的锁池中,等待获取锁.
    5:B线程执行完同步方法,释放锁.A线程获得锁,继续执行同步方法.

  5.  

    线程通信-使用Lock和Condition接口:
    Lock机制根本就没有同步锁了,所以Lock机制不能调用wait和notify方法.
    提供了Lock机制的同时提供了处理Lock机制的通信控制的Condition接口.
          1):使用Lock机制取代synchronized 代码块和synchronized 方法.
          2):使用Condition接口对象的await,signal,signalAll方法取代Object类中的wait,notify,notifyAll方法.

    多线程通信的很容易造成死锁,无法解决,只能避免:
    当A线程等待由B线程持有的锁,而B线程正在等待A线程持有的锁时,发生死锁现象
    避免死锁法则: 当多个线程都要访问共享的资源A,B,C时,保证每一个线程都按照相同的顺序去访问他们,比如都先访问A,接着B,最后C.

    线程对象的状态存放在Thread类的内部类(State)中:

    1:新建状态(new):
       Thread t = new Thread();//此时t就属于新建状态
       当新建状态下调用start方法,此时从新建状态进入可运行状态.
       start方法只能调用一次,否则报错:IllegalThreadStateException.
    2:可运行状态(runnable):分ready和running。表示就绪状态和运行状态。
        就绪状态:线程对象调用start方法之后,等待JVM的调度
        运行状态:线程对象获得JVM调度,如果存在多个CPU,那么允许多个线程并行运行.
    3:阻塞状态(blocked):正在运行的线程因为某些原因放弃CPU,暂时停止运行,就会进入阻塞状态.
             此时JVM不会给线程分配CPU,直到线程重新进入就绪状态,才有机会转到运行状态..

  6. ➢ 等待阻塞:运行的线程执行 wait 方法, jvm 会把当前
    线程放入到等待队列
    ➢ 同步阻塞:运行的线程在获取对象的同步锁时,若该同
    步锁被其他线程锁占用了,那么 jvm 会把当前的线程
    放入到锁池中
    ➢ 其他阻塞:运行的线程执行 Thread.sleep 或者 t.join 方
    法,或者发出了 I/O 请求时, JVM 会把当前线程设置
    为阻塞状态,当 sleep 结束、 join 线程终止、 io 处理完
    毕则线程恢复

       阻塞状态的两种情况:
                1):当A线程处于运行过程时,试图获取同步锁时,却被B线程获取.此时JVM把当前A线程存到对象的锁池中,A线程进入阻塞状态.
                2):当线程处于运行过程时,发出了IO请求时,此时进入阻塞状态.        
    4:等待状态(waiting)(等待状态只能被其他线程唤醒):此时使用的无参数的wait方法,
           1):当线程处于运行过程时,调用了wait()方法,此时JVM把当前线程存在对象等待池中.
    5:计时等待状态(timed waiting)(使用了带参数的wait方法或者sleep方法)
           1):当线程处于运行过程时,调用了wait(long time)方法,此时JVM把当前线程存在对象等待池中.
           2):当前线程执行了sleep(long time)方法.
    6:终止状态(terminated):通常称为死亡状态,表示线程终止.
            1):正常执行完run方法而退出(正常死亡).
            2):遇到异常而退出(意外死亡).

  7. 线程休眠:进入计时等待状态。
    方法:static void sleep(long millis)
    调用sleep后,当前线程放弃CPU,不会被执行。此状态下的线程不会释放同步锁/同步监听器.

  8. 联合线程:
    线程的join方法表示一个线程等待另一个线程完成后才执行。join方法被调用之后,(哪个)线程对象处于阻塞状态。
    也称为联合线程,就是说把当前线程和当前线程所在的线程联合成一个线程。

  9. 后台线程:也称为“守护线程",为其他线程提供服务。JVM的垃圾回收线程
    特点:若所有的前台线程都死亡,后台线程自动死亡,前台线程没有结束,后台线程是不会结束的。
    判断线程对象是否为后台线程:使用thread.isDaemon()。
    前台线程创建的线程默认是前台线程,可以通过setDaenon(true)方法设置为后台线程,并且当且仅当后台线程创建的新线程时,新线程是后台线程。
    thread.setDaemon(true),该方法必须在start方法调用前,否则出现IllegalThreadStateException异常。

  10. 线程优先级只和线程获得执行机会的次数多少有关
    MAX_PRIORITY=10,最高优先级
    MIN_PRIORITY=1,最低优先级
    NORM_PRIORITY=5,默认优先级
     int getPriority() :返回线程的优先级。
     void setPriority(int newPriority) : 更改线程的优先级。
    每个线程都有默认优先级,主线程默认优先级为5,如果A线程创建了B线程,那么B线程和A线程具有相同优先级.

  11. 线程礼让
    yield方法:愿意让出CPU资源,调度器可以忽略该提示。
    调用该方法之后,线程对象进入就绪状态,
    sleep方法和yield方法的区别:
      1):都能使当前处于运行状态的线程放弃CPU
      2):sleep方法会给其他线程运行机会,但是不考虑其他线程的优先级;yield方法只会给相同优先级或者更高优先级的线程运行的机会.
      3):调用sleep方法后,线程进入计时等待状态,调用yield方法后,线程进入就绪状态.

  12. Timer类,可以定时执行特定的任务.
    TimerTask类表示定时器执行的某一项任务.
    常用方法:
    schedule(TimerTask task,long delay,long period):
    schedule(TimerTask task,long delay):
    -----------------------------------------------------------------
    ThreadGroup类表示线程组,可以通过Thread构造器指定其所属的线程组.
    Thread(ThreadGroup group,String name);
    如果A线程创建了B线程,如果没有设置B线程的分组,那么B线程加入到A线程的线程组.
    一旦线程加入某个线程组,直到线程死亡,不能在中途修改线程的分组.
    当Java程序运行时,JVM会创建名为main的线程组,在默认情况下,所有的线程都该在改线程组下.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值