001package arcommon;
002
003import java.util.HashMap;
004
005import arcommon.exception.MyLog;
006
007public abstract class MyThread extends Thread {
008
009    private static HashMap<String, Integer> threadNames;
010    
011    public static final int DEFAULT_TIMEOUT = 5000;
012    
013    private boolean requestedToStop;
014
015    public MyThread() {
016        String numberName = calculateNumberName(null);
017        setName(numberName);
018    }
019    
020    public MyThread(String name) {
021        this(name, true);
022    }
023    
024    public MyThread(String name, boolean useNumber) {
025        super(useNumber ? "" : name);
026        
027        if (useNumber) {
028            String numberName = calculateNumberName(name);
029            setName(numberName);
030        }
031    }
032    
033    private synchronized String calculateNumberName(String name) {
034        if (threadNames == null) {
035            threadNames = new HashMap<String, Integer>();
036        }
037        if (name == null || name.length() == 0) {
038            name = getClass().getSimpleName();
039            
040            if (name.length() == 0) {
041                name = getClass().getName();
042                int index = name.lastIndexOf('.');
043                if (index != -1) {
044                    name = name.substring(index + 1);
045                }
046            }
047        }
048        
049        Integer number = threadNames.get(name);
050        if (number == null) {
051            number = Integer.valueOf(1);
052        }
053        String result = name + " " + number;
054        
055        number = Integer.valueOf(number.intValue() + 1);
056        threadNames.put(name, number);
057        
058        return result;
059    }
060    
061    public void run() {
062        beforeLoop();
063        while (!isRequestedToStop()) {
064            doLoop();
065        }
066        afterLoop();
067    }
068
069    protected void beforeLoop() {
070        ;
071    }
072    
073    protected void doLoop() {
074        throw new RuntimeException("Code error: Implement doLoop() or override run() in the class " + getClass().getName());
075    }
076
077    protected void afterLoop() {
078        ;
079    }
080    
081    public void blockUntilStoppedWithTimeout() {
082        blockUntilStoppedWithTimeout(DEFAULT_TIMEOUT);
083    }
084    
085    public void blockUntilStoppedWithTimeout(int timeoutTimeInMilliseconds) {
086        requestToStop();
087        if (Thread.currentThread() == this) {
088            throw new RuntimeException("Called on it self!!");
089        }
090        int time = 0;
091        int timeoutTime = timeoutTimeInMilliseconds / 10;
092        while (time < timeoutTime && isAlive()) {
093            Util.sleep(10);
094            if (++time % 20 == 0 && time > 30) {
095                Util.printMessageWithSourceLine("Blocking (" + time * 10 + "ms. " + getName() + " (" + getClass().getName() + "))");
096            }
097        }
098        if (isAlive()) {
099            MyLog.logError("Timeout");
100        }
101    }
102    
103    public void blockUntilStopped() {
104        requestToStop();
105        while (isAlive()) {
106            Util.sleep(10);
107        }
108    }
109    
110    public void requestToStop() {
111        setRequestedToStop(true);
112    }
113
114    public boolean isRequestedToStop() {
115        return requestedToStop;
116    }
117
118    public void setRequestedToStop(boolean prequestedToStop) {
119        requestedToStop = prequestedToStop;
120    }
121}