Skip to main content

Any way to know current EDT queue size

2 replies [Last post]
cmelnick
Offline
Joined: 2004-06-07

Is there any way to determine how many items are currently queued to be processed by the EDT? We are trying to assemble some monitors for various queues throughout our application, and have several producer/consumer queues that end up pushing UI updates to the EDT. We would like to be able to watch the effect that throttling the producers has on how busy the EDT is.

[Producer thread] --> [Blocking Queue] <-- [Consumer Thread] --> [EDT Thread]

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
p_a_harvey
Offline
Joined: 2008-02-25

But since you asked for the SIZE of the queue, here is a reflection-based solution that might do what you want. Of course, this is digging into private APIs and so will only work with certain JREs. I've only tested it on Sun's Java 1.6 JRE and it seems to work there.

The method you are interested in is EventQueueCounter.getQueueSize(). The main() method is just demonstrating how you could (inefficiently) poll for the queue size....

[code]
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.lang.reflect.Field;

import javax.swing.JFrame;

public class EventQueueCounter {
private static Field queuesField;

private static Field headField;

private static Field nextField;

static {
try {
ClassLoader loader = ClassLoader.getSystemClassLoader();
queuesField = loader.loadClass("java.awt.EventQueue").getDeclaredField("queues");
headField = loader.loadClass("java.awt.Queue").getDeclaredField("head");
nextField = loader.loadClass("java.awt.EventQueueItem").getDeclaredField("next");
queuesField.setAccessible(true);
headField.setAccessible(true);
nextField.setAccessible(true);
} catch (Exception e) {
e.printStackTrace();
}
}

public static int getQueueSize() {
int count = 0;
try {
EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
synchronized (eventQueue) {
Object[] queues = (Object[]) queuesField.get(eventQueue);
for (Object queue : queues)
if (queue != null) {
Object head = headField.get(queue);
while (head != null) {
count++;
Object next = nextField.get(head);
head = head == next ? null : next;
}
}
}

} catch (Exception e) {
e.printStackTrace();
}
return count;
}

public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setVisible(true);

int oldSize = 0;
while (true) {
int newSize = getQueueSize();
if (newSize != oldSize) {
System.out.println("time=" + System.currentTimeMillis() + " queue=" + newSize);
oldSize = newSize;
}
}
}
}
[/code]

p_a_harvey
Offline
Joined: 2008-02-25

I can't claim to be an expert, but one solution I found is to monitor all AWT event dispatches. This won't tell you the SIZE of the queue, but will tell you how many events are going through per second. The following shows how to use AWTEventListener to achieve this:

[code]
public class EventQueueLoad {
private static int eventCount = 0;

public static void main(String[] args) throws InterruptedException {

// Create a JFrame, just for demonstration purposes
JFrame frame = new JFrame();
frame.setVisible(true);

// Create and attach a listener that counts events
AWTEventListener listener = new AWTEventListener() {
public void eventDispatched(AWTEvent event) {
eventCount++;
}
};
Toolkit.getDefaultToolkit().addAWTEventListener(listener, -1);

// Print and reset the number of events every second
while (true) {
Thread.sleep(1000);
System.out.println(eventCount + " / sec");
eventCount = 0;
}

}
}
[/code]