36 @SuppressWarnings(
"serial")
37 static class ThreadGroupSync
extends SingleThreadSync {
42 holdCountAdditionOwner = 0;
43 waitingOrigOwner =
null;
46 public final void incrHoldCount(
final Thread t) {
47 super.incrHoldCount(t);
49 holdCountAdditionOwner++;
53 public final void decrHoldCount(
final Thread t) {
54 super.decrHoldCount(t);
56 holdCountAdditionOwner--;
59 public final int getAdditionalOwnerHoldCount() {
60 return holdCountAdditionOwner;
64 return super.isOwner(t);
66 public final void setWaitingOrigOwner(
final Thread origOwner) {
67 waitingOrigOwner = origOwner;
69 public final Thread getWaitingOrigOwner() {
70 return waitingOrigOwner;
73 public final boolean isOwner(
final Thread t) {
74 if(getExclusiveOwnerThread()==t) {
77 for(
int i=threadNum-1; 0<=i; i--) {
85 public final int getAddOwnerCount() {
88 public final void addOwner(
final Thread t)
throws IllegalArgumentException {
91 throw new InternalError(
"XXX");
93 threads =
new Thread[4];
95 for(
int i=threadNum-1; 0<=i; i--) {
97 throw new IllegalArgumentException(
"Thread already added: "+t);
100 if (threadNum == threads.length) {
101 threads = Arrays.copyOf(threads, threadNum * 2);
103 threads[threadNum] = t;
107 public final void removeAllOwners() {
108 for(
int i=threadNum-1; 0<=i; i--) {
114 public final void removeOwner(
final Thread t)
throws IllegalArgumentException {
115 for (
int i = 0 ; i < threadNum ; i++) {
116 if (threads[i] == t) {
118 System.arraycopy(threads, i + 1, threads, i, threadNum - i);
119 threads[threadNum] =
null;
123 throw new IllegalArgumentException(
"Not an owner: "+t);
126 String addOwnerToString() {
127 final StringBuilder sb =
new StringBuilder();
128 for(
int i=0; i<threadNum; i++) {
132 sb.append(threads[i].getName());
134 return sb.toString();
138 private int holdCountAdditionOwner;
139 private Thread[] threads;
140 private int threadNum;
141 private Thread waitingOrigOwner;
145 super(
new ThreadGroupSync());
156 return ((ThreadGroupSync)
sync).isOriginalOwner(thread) ;
161 public final void addOwner(
final Thread t)
throws RuntimeException, IllegalArgumentException {
163 final Thread cur = Thread.currentThread();
164 final ThreadGroupSync tgSync = (ThreadGroupSync)
sync;
165 if(!tgSync.isOriginalOwner(cur)) {
166 throw new IllegalArgumentException(
"Current thread is not the original owner: orig-owner: "+tgSync.getOwner()+
", current "+cur+
": "+
toString());
168 if(tgSync.isOriginalOwner(t)) {
169 throw new IllegalArgumentException(
"Passed thread is original owner: "+t+
", "+
toString());
175 public final void unlock(
final Runnable taskAfterUnlockBeforeNotify) {
177 final Thread cur = Thread.currentThread();
178 final ThreadGroupSync tgSync = (ThreadGroupSync)
sync;
180 if( tgSync.getAddOwnerCount()>0 ) {
182 System.err.println(
"--- LOCK XR (tg) "+
toString()+
", cur "+threadName(cur)+
" -> owner...");
184 if( tgSync.isOriginalOwner(cur) ) {
186 if( tgSync.getHoldCount() - tgSync.getAdditionalOwnerHoldCount() == 1 ) {
188 tgSync.setWaitingOrigOwner(cur);
190 while ( tgSync.getAdditionalOwnerHoldCount() > 0 ) {
193 }
catch (
final InterruptedException e) {
198 tgSync.setWaitingOrigOwner(
null);
199 Thread.interrupted();
201 tgSync.removeAllOwners();
203 }
else if( tgSync.getAdditionalOwnerHoldCount() == 1 ) {
205 final Thread originalOwner = tgSync.getWaitingOrigOwner();
206 if(
null != originalOwner ) {
207 originalOwner.interrupt();
212 System.err.println(
"++ unlock(X): currentThread "+cur.getName()+
", lock: "+
this.toString());
213 System.err.println(
"--- LOCK X0 (tg) "+
toString()+
", cur "+threadName(cur)+
" -> unlock!");
215 super.unlock(taskAfterUnlockBeforeNotify);
220 public final void removeOwner(
final Thread t)
throws RuntimeException, IllegalArgumentException {
227 final ThreadGroupSync tgSync = (ThreadGroupSync)
sync;
228 final int hc =
sync.getHoldCount();
229 final int addHC = tgSync.getAdditionalOwnerHoldCount();
230 return syncName()+
"[count "+hc+
" [ add. "+addHC+
", orig "+(hc-addHC)+
231 "], qsz "+
sync.getQSz()+
", owner "+threadName(
sync.getOwner())+
", add.owner "+tgSync.addOwnerToString()+
"]";