第4章-Balking

4.1 模式简介

  1. 我正坐在餐馆中,合计着吃点什么。想好之后,我举起手示意服务员点菜。于是,看到我举手的服务员就向我走来点菜。这时,另一位服务员也看到我举手示意了,但他看到已经有一位服务员走向了我,所以就没有再过来。
  2. 如果现在不适合执行这个操作,或者没必要执行这个操作,就停止处理,直接返回——这就是Balking模式。
  3. 所谓Balk,就是 “停止并返回” 的意思。
  4. Balking 模式与Guarded Suspension模式一样,也存在守护条件。在Balking模式中,如果守护条件不成立,则立即中断处理。这与Guarded Suspension模式有所不同,因为Guarded Suspension模式是一直等待至可以运行

4.3 Balking模式中的角色

4.3.1 GuardedObject

  1. GuardedObject角色是一个拥有被防护的方法(guardedMethod)的类。当线程执行guardedMethod方法时,若守护条件成立,则执行实际的处理。而当守护条件不成立时,则不执行实际的处理,直接返回。守护条件的成立与否,会随着GuardedObject角色的状态变化而发生变化。
  2. 除了guardedMethod之外,GuardedObject角色还有可能有其他来改变状态的方法(stateChangingMethod)。

4.3.2 类图和Timethreads图

类图

Timethreads图

4.4 拓展思路的要点

4.4.1 何时使用

  1. 并不需要执行时
  • 在这里执行balk能够提高程序性能。
  1. 不需要等待守护条件成立时
  • Balking模式的特点就是“不进行等待”。若守护条件不成立时,想要立即返回并进入下一个操作,就可以使用Balking模式。这能够提高程序的响应性
  1. 守护条件仅在第一次成立时
  • 具体实例经常是实例的初始化和终止处理等。例如下列代码中的Something类。在这里,initialized字段表示初始化是否已经完成。当init方法被调用后,它会首先来检查initialized字段。
  • 如果initialized字段的值为true,就表明字段已经初始化了,此时需要使用return执行balk(也可以设计成抛出异常)。
  • 如果initialized字段的值为false,就需要调用doInit方法执行实际的初始化处理,然后将initialized字段设置为true,来记录“初始化已经完成了”这一事实(这相当于没有stateChangingMethod方法的情况)。
public class P448_Reorder.Something 
{
    private boolean initialized = false;
    public synchronized void init() 
    {
        if (initialized) // 此处不能使用while,因为initialized字段一旦为true就不会再变为false
        {
            return;
        }
        doInit();
        initialized = true;
    }
    private void doInit() 
    {
        // 实际的初始化处理
    }
}

4.4.2 balk结果的表示方式

  1. 忽略balk。
  2. 通过返回值来表示balk。
  3. 通过异常来表示balk的发生。

4.6 超时

4.6.1 Timeout

  1. 在Balking模式中,当守护条件不成立时,线程会直接balk并返回。
  2. 在Guarded Suspension模式中,当守护条件不成立时,线程会一直等待到成立为止。
  3. 介于 “直接balk并返回” 和 “等待到守护条件成立为止” 这两种极端的处理方法之间,还有一种处理方法,那就是 “在守护条件成立之前等待一段时间”。在守护条件成立之前等待一段时间,如果到时条件还未成立,则直接balk。我们将这种处理称为guarded timed 或timeout。

4.6.2 wait何时终止

  1. notify方法执行时。
  2. notifyAll方法执行时。
  3. interrupt方法执行时。
  4. 超时发生时。

其中notify和notifyAll这两个方法是用于调用实例的,而interrupt方法是用于调用线程的。当被interrupt时,等待队列中的线程(与被notify、notifyAll时一样)会重新获取obj的锁,然后抛出InterruptedException异常。

4.6.3 synchronized和wait状态的区别

对于线程的下列两种状态:

  1. 想要使用synchronized获取锁但处于阻塞状态
  2. 执行wait并进入等待队列的状态

在这两种状态下,线程都是不运行的,这一点两者非常相似,但也存在不同:

  • 我们无法让状态1下的线程发生超时。这是因为,synchronized方法和synchronized代码块都无法设置超时时间。
  • 另外,即使对状态1下的线程执行interrupt,也不会抛出InterruptedException异常。线程必须在获取锁并进入synchronized之后,调用那些会注意着中断状态的方法,如wait、sleep、join等,或者使用isInterrupted方法或interrupted方法检查中断状态,自己抛出去。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值