blob: f63bbfba1243b7c4606c64443dc441494ba4016b [file] [log] [blame]
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.apache.batik.util;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.apache.batik.test.AbstractTest;
import org.apache.batik.test.TestReport;
public class RunnableQueueTest extends AbstractTest {
public int nThreads;
public int activeThreads;
public Random rand;
public RunnableQueue rq;
/**
* Creates a new RunnableQueueTest.
* @param nThreads number of runnables to queue
*/
public RunnableQueueTest(int nThreads) {
this.nThreads = nThreads;
}
public RunnableQueueTest(Integer nThreads) {
this((nThreads==null)?10:nThreads.intValue());
}
/**
* Returns this Test's name
*/
public String getName() {
return "RunnableQueue Stress Test";
}
/**
* This method will only throw exceptions if some aspect
* of the test's internal operation fails.
*/
public TestReport runImpl() throws Exception {
rq = RunnableQueue.createRunnableQueue();
List l = new ArrayList(nThreads);
rand = new Random(2345);
// Two switch flickers to make things interesting...
l.add(new SwitchFlicker());
l.add(new SwitchFlicker());
for (int i=0; i<nThreads; i++) {
Runnable rqRable = new RQRable(i, rand.nextInt(50)+1);
l.add(new TPRable(rq, i, rand.nextInt(4)+1,
rand.nextInt(500)+1, 20, rqRable));
}
synchronized (this) {
ThreadPounder tp = new ThreadPounder(l);
tp.start();
activeThreads = nThreads;
while (activeThreads != 0) {
wait();
}
}
System.exit(0);
return null;
}
public class SwitchFlicker implements Runnable {
public void run() {
boolean suspendp, waitp;
int time;
while (true) {
try {
synchronized (rand) {
suspendp = rand.nextBoolean();
waitp = rand.nextBoolean();
time = rand.nextInt(500);
}
if (suspendp) {
// 1/2 of the time suspend, 1/2 time wait, 1/2 the
// time don't
rq.suspendExecution(waitp);
System.out.println("Suspended - " +
(waitp?"Wait":"Later"));
Thread.sleep(time/10);
} else {
// 1/2 the time resume
rq.resumeExecution();
System.out.println("Resumed");
Thread.sleep(time);
}
} catch(InterruptedException ie) { }
}
}
}
public static final int INVOKE_LATER = 1;
public static final int INVOKE_AND_WAIT = 2;
public static final int PREEMPT_LATER = 3;
public static final int PREEMPT_AND_WAIT = 4;
public class TPRable implements Runnable {
RunnableQueue rq;
int idx;
int style;
long repeatDelay;
int count;
Runnable rqRable;
TPRable(RunnableQueue rq, int idx,
int style,
long repeatDelay, int count,
Runnable rqRable) {
this.rq = rq;
this.idx = idx;
this.style = style;
this.repeatDelay = repeatDelay;
this.count = count;
this.rqRable = rqRable;
}
public void run() {
try {
while (count-- != 0) {
switch (style) {
case INVOKE_LATER:
synchronized (rqRable) {
System.out.println(" InvL #" + idx);
rq.invokeLater(rqRable);
System.out.println("Done InvL #" + idx);
rqRable.wait();
}
break;
case INVOKE_AND_WAIT:
System.out.println(" InvW #" + idx);
rq.invokeAndWait(rqRable);
System.out.println("Done InvW #" + idx);
break;
case PREEMPT_LATER:
synchronized (rqRable) {
System.out.println(" PreL #" + idx);
rq.preemptLater(rqRable);
System.out.println("Done PreL #" + idx);
rqRable.wait();
}
break;
case PREEMPT_AND_WAIT:
System.out.println(" PreW #" + idx);
rq.preemptAndWait(rqRable);
System.out.println("Done PreW #" + idx);
break;
}
if (repeatDelay < 0)
break;
Thread.sleep(repeatDelay);
}
} catch (InterruptedException ie) {
}
synchronized(RunnableQueueTest.this) {
activeThreads--;
RunnableQueueTest.this.notify();
}
}
}
public static class RQRable implements Runnable {
int idx;
long dur;
RQRable(int idx, long dur) {
this.idx = idx;
this.dur = dur;
}
public void run() {
try {
System.out.println(" B Rable #" + idx);
Thread.sleep(dur);
System.out.println(" E Rable #" + idx);
synchronized (this) {
notify();
}
} catch (InterruptedException ie) { }
}
}
public static void main(String []args) {
RunnableQueueTest rqt = new RunnableQueueTest(20);
try {
rqt.runImpl();
} catch (Exception e) {
e.printStackTrace();
}
}
}