一、Balking设计模式
一、问题:
一个线程要去执行某个操作。但是,在发现这个操作已经被别的线程做了,于是,就没有必要再去做这样的一个操作了。面对这种问题的设计方案是多线程设计模式中的Balking模式。
二、Balking Pattern应用场景说明
角色:一个顾客,两个服务员
顾客规则:
顾客向服务员发出20次服务请求,发出一次请求之后,随机等待一段时间,再发出下一次请求。如果,上一次的请求没有得到waiter的服务,那么放弃执行请求操作。
服务员规则:
两个服务员一起服务20次,顾客没有服务请求,那么放弃提供服务操作,直接返回。
Balking Pattern就是当不再适合或者没有必要进行这个操作时,就直接放弃进行这个操作而直接返回。
代码说明:
1. 顾客---Customer类
n 属性-------------------------------
Ø 服务请求标志属性: private boolean m_calledService= false,取值为false表示没有服务请求,否则有服务请求。
Ø 顾客名属性: private String m_Name;
n 方法---------------------------------
Ø 获得服务的方法:
/**
* @param serviceName服务名称
* @param waiterName提供服务的服务员的名称
* 这一个方法是Balking Pattern的核心
* 如果警戒条件不成立,那么直接返回,不再执行操作
*/
public synchronizedboolean GetService(String waiterName , String serviceName){
// TODO Auto-generatedconstructor stub
//如果,没有服务要求,那么直接返回
if( ! m_calledService){
System.out.println( "no service need----------------------------------------------");
return false;
}
System.out.println(waiterName + "提供服务-- "+serviceName);
m_calledService = false;
return true;
}
Ø 顾客向服务员发出请求的方法:
/**
* @param serviceName服务名
* 向服务员发出服务请求
* 当顾客已经是发出服务要求的状态,那么没有必要
* 执行更改状态的操作,直接返回false
* 所以,这也是一个Balking Pattern的设计
*/
public synchronized boolean CallService(String serviceName) {
if( m_calledService){
System.out.println( "not get service----------------------------------------------");
return false;
}
m_calledService = true;
System.out.println(m_Name + "需要服务 : "+serviceName );
return true;
}
Ø 构造函数
/**
* @param name
* 构造函数
*/
public Customer(String name) {
m_Name = name;
// TODO Auto-generatedconstructor stub
}
2. 服务请求线程—CallServiceThread类,是一个线程类(通过集成Thread类实现)
n 属性-------------------------------
顾客:private Customer m_Customer;
n 方法---------------------------------
Ø 构造函数:
/**
* @param Customer
* 构造函数
*/
public CallServiceThread(Customer customer) {
m_Customer = customer ;
// TODO Auto-generatedconstructor stub
}
Ø 线程执行方法
/**
* @param null
* 线程run方法
* 线程使得顾客发出一百次服务要求
*/
public void run(){
int i= 0 ;
Objectobj = new Object();
synchronized(obj){
while(i< 20){
if(m_Customer.CallService("No_"+i)){
i++ ;
}
//等待一秒钟
try {
Randomrand = new Random();
obj.wait(rand.nextInt(1000));
}catch(InterruptedException e){
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
}
3. 服务员线程类—Waiter类(继承了Thread类)
n 属性----------------
顾客:private Customer m_Customer;
计数器:private staticint i = 0 ; //满二十次计数线程
n 方法---------------------------------
Ø 构造函数
/**
* @param name,服务员名
* @param customer,顾客对象实例
* 构造函数
*/
public Waiter(String name , Customer customer){
super(name);
m_Customer = customer ;
// TODO Auto-generatedconstructor stub
}
Ø 线程运行函数:
/**
* @param null
* 服务员随机等待一段时间后为顾客提供服务
*/
public void run(){
Objectobj = new Object();
synchronized(obj){
while(i< 20){
if(m_Customer.GetService(super.getName() , "No_"+i)){
i++ ;
}
//随机等待一段时间
try {
Randomrand = new Random();
obj.wait(rand.nextInt(1000));
}catch (InterruptedException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
}
}
4. 测试类—Main
public class Main {
/**
*
*/
public Main() {
// TODO Auto-generatedconstructor stub
}
/**
* @param args
*/
public static void main(String[] args){
// TODO Auto-generatedmethod stub
Customercustomer = new Customer("顾客1");
CallServiceThreadchanger = new CallServiceThread(customer);
Waiterwaiter1 = new Waiter("waiter1",customer);
Waiterwaiter2 = new Waiter("waiter2",customer);
changer.start();
waiter1.start();
waiter2.start();
}
测试结果:
顾客1需要服务 : No_0
waiter1提供服务-- No_0
no service need----------------------------------------------
no service need----------------------------------------------
顾客1需要服务 : No_1
waiter2提供服务-- No_1
顾客1需要服务 : No_2
waiter1提供服务-- No_2
no service need----------------------------------------------
顾客1需要服务 : No_3
waiter2提供服务-- No_3
顾客1需要服务 : No_4
waiter2提供服务-- No_4
no service need----------------------------------------------
顾客1需要服务 : No_5
not getservice----------------------------------------------
waiter1提供服务-- No_5
no service need----------------------------------------------
顾客1需要服务 : No_6
waiter1提供服务-- No_6
no service need----------------------------------------------
no service need----------------------------------------------
no service need----------------------------------------------
顾客1需要服务 : No_7
waiter2提供服务-- No_7
no service need ----------------------------------------------
no service need----------------------------------------------
no service need----------------------------------------------
no service need----------------------------------------------
顾客1需要服务 : No_8
waiter1提供服务-- No_8
no service need----------------------------------------------
no service need----------------------------------------------
no service need----------------------------------------------
no service need----------------------------------------------
顾客1需要服务 : No_9
not getservice----------------------------------------------
waiter1提供服务-- No_9
no service need----------------------------------------------
顾客1需要服务 : No_10
waiter1提供服务-- No_10
顾客1需要服务 : No_11
waiter1提供服务-- No_11
no service need----------------------------------------------
no service need----------------------------------------------
no service need----------------------------------------------
顾客1需要服务 : No_12
waiter1提供服务-- No_12
no service need----------------------------------------------
顾客1需要服务 : No_13
waiter1提供服务-- No_13
顾客1需要服务 : No_14
waiter2提供服务-- No_14
顾客1需要服务 : No_15
waiter1提供服务-- No_15
no service need----------------------------------------------
no service need----------------------------------------------
顾客1需要服务 : No_16
waiter1提供服务-- No_16
no service need----------------------------------------------
no service need----------------------------------------------
顾客1需要服务 : No_17
waiter2提供服务-- No_17
no service need----------------------------------------------
no service need----------------------------------------------
顾客1需要服务 : No_18
not getservice----------------------------------------------
waiter1提供服务-- No_18
no service need----------------------------------------------
顾客1需要服务 : No_19
waiter2提供服务-- No_19
关于Balking Pattern的适用性总结:
u 当不需要刻意去执行的时候
u 不想等待警戒条件成立的时候
u 警戒条件只有第一次成立的时候