package com.e2u.thread; import java.util.*; public class SerializedOperBooker { private static boolean isLog = true; //Simple init way to avoid multi-threading violation. private static SerializedOperBooker instance = new SerializedOperBooker(); //The book data private Map<String, LinkedList> bookMap = null; private SerializedOperBooker() { bookMap = new HashMap<String, LinkedList>(); } public static SerializedOperBooker getInstance() { return instance; } private static void info(String str) { if(isLog) { System.out.println(str); } } public synchronized void book(String operObjName, Object bookeeID) { LinkedList que = null; //No other operations to this object if(!bookMap.containsKey(operObjName)) { que = new LinkedList(); bookMap.put(operObjName, que); } //there are some other operations to this object else { que = bookMap.get(operObjName); } que.add(bookeeID); info("[book]: operObjName=" + operObjName + ", bookeeID=" + bookeeID); } public synchronized void unbook(String operObjName) { LinkedList que = bookMap.get(operObjName); if(que == null || que.isEmpty()) { info("fatal error. que is " + que + ", when unbook " + operObjName); return; } que.remove(); if(que.isEmpty()) { bookMap.remove(operObjName); } info("[unbook]: operObjName=" + operObjName); notifyAll(); } public synchronized void checkExecutable(String operObjName, Object bookeeID) { LinkedList que = bookMap.get(operObjName); if(que == null || que.isEmpty()) { info("fatal error. que is " + que + ", when checkExecutable " + operObjName); return; } Object bookee = null; for(bookee = que.peek(); bookee != bookeeID; bookee = que.peek()) { //The bookee should not be null if(bookee == null) { info("fatal error. bookee is null when checkExecutable " + operObjName); return; } info("The object [" + operObjName + "] is now operated by [" + bookee + "], wait."); try { //Wait until the condition changed wait(); } catch(InterruptedException e) { //ignore } } info("It's the turn of [" + bookeeID + "] now for object [" + operObjName + "]"); } }