目的
如果要对未处于正确状态的对象执行方法,请使用Guarded Suspension Pattern来处理某种情况。
维基百科说
在并发编程中,guarded suspension是用于管理操作的软件设计模式,其需要获取锁定并且在执行操作之前满足前提条件。Guarded Suspension Pattern通常应用于面向对象程序中的方法调用,并涉及暂停方法调用和调用线程,直到满足前提条件(充当保护)。
源代码
实现基于GuardedQueue,它有两个方法:get和put,条件是我们无法从空队列中获取,因此当线程试图破坏条件时,我们调用Object的wait方法,当其他线程将一个元素放入队列时,它会通知等待者,现在他可以从队列中获取。
类图
第1步:创建GuardedQueue类,它是Guarded Suspension Pattern的实现。
当您想要对未处于正确状态的对象执行方法时,使用Guarded Suspension Pattern来处理这种情况。
public class GuardedQueue { private static final Logger LOGGER = LoggerFactory.getLogger(GuardedQueue.class); private final Queue<Integer> sourceList;
public GuardedQueue() { this.sourceList = new LinkedList<>(); }
/** * @return last element of a queue if queue is not empty */ public synchronized Integer get() { while (sourceList.isEmpty()) { try { LOGGER.info("waiting"); wait(); } catch (InterruptedException e) { e.printStackTrace(); } } LOGGER.info("getting"); return sourceList.peek(); }
/** * @param e number which we want to put to our queue */ public synchronized void put(Integer e) { LOGGER.info("putting"); sourceList.add(e); LOGGER.info("notifying"); notify(); } }
|
第2步:让我们测试一下Guarded Suspension Pattern。
public class App { /** * Example pattern execution * * @param args - command line args */ public static void main(String[] args) { GuardedQueue guardedQueue = new GuardedQueue(); ExecutorService executorService = Executors.newFixedThreadPool(3);
//here we create first thread which is supposed to get from guardedQueue executorService.execute(() -> { guardedQueue.get(); } ); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } executorService.execute(() -> { guardedQueue.put(20); } ); executorService.shutdown(); try { executorService.awaitTermination(30, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } }
}
|
适用性
当开发人员知道方法执行将在有限的时间内被阻止时,使用Guarded Suspension模式。