I am working on a smart meter simulator for performance tests where I initialize several thousand (5k and more) connections in multiple parallel threads using the following code
private void initializeMediaTcp(int port) throws Exception {
LOG.debug("Initialize Media Tcp port: {}", port);
Media = new GXNet(NetworkType.TCP, port);
Media.setTrace(TraceLevel.VERBOSE);
Media.addListener(this);
Media.open();
LOG.trace("Initialize Media Tcp finished", port);
}
I use the 1.0.11 version of the gurux.net library. Sometimes few (1 or 2 from 5000) threads get stuck during the Media.open() call. Thread stack trace analysis using JConsole showed the possible root of the problem
Name: SimThread-custom-39379
State: WAITING on gurux.net.ListenerThread@7b54b36
Total blocked: 0 Total waited: 1
Stack trace:
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:502)
gurux.net.ListenerThread.waitUntilRun(ListenerThread.java:80)
gurux.net.GXNet.open(GXNet.java:450)
sk.kedros.electrometer.simulator.ElectrometerSimulatorBase.initializeMediaTcp(ElectrometerSimulatorBase.java:99)
sk.kedros.electrometer.simulator.ElectrometerSimulatorBase.intializeOnPort(ElectrometerSimulatorBase.java:78)
sk.kedros.electrometer.app.SimulatorThread.run(SimulatorThread.java:56)
java.lang.Thread.run(Thread.java:745)
I assume the reason behind this is that ListenerThread.run() is executed before ListenerThread.waitUntilRun() is called, so the notifyAll() has no effect.
If an easy solution is not possible, adding a wait timeout argument to the GXNet.open() method would be a welcome solution as well. Thank You.
progress
Is there anything else I can do to help with this issue? Also I would like to know when the solution to this problem will be available.
Progress
Hi,
We have tested this with it works. :-)
Are you creating ports on main thread or do you have own thread where you create them?
Are you using Linux or Windows?
BR,
Mikko
I'm glad it works :). It is
I'm glad it works :). It is not easy to reproduce the problem, you need to stress your CPU quite hard and use multiple threads. That's our case: the application uses new threads to initialize connections on a GNU/Linux environment. Also we use a counting semaphore (16 permits) to keep the simultaneous number of GXNet.open() calls under control. Tests are executed on a machine with a Core i5 (4 CPU cores) CPU. About 1 in 10 tests causes this problem, but you have to create at least 5000 connections per test. Increasing the number of connections also increases your chance to reproduce this problem.
Thank You.
Best wishes,
Jozef Balga
Kedros, a.s.
Hi,
Hi,
Try to use version 1.0.12. We have added synchronize.
BR,
Mikko
Thank You, but the new
Thank You, but the new version did not solve my problem. Let me explain, how I see the problem here:
listenerThread.start();
listenerThread.waitUntilRun();
No one guarantees that these 2 commands will be executed immediately after each other without interruption. Imagine the situation:
1. listenerThread.start() is called
2. the OS decides that it's time to let a different thread to run, so this main thread is "suspended"
3. the OS decides that the native thread created by listenerThread.start() should be executed
4. ListenerThread.notifyAll() is called, but there is no thread waiting to be notified, so nothing happens
5. the ListenerThread.run() finishes
6. the OS decides to run the previously suspended main thread, listenerThread.waitUntilRun() is called, but the main thread will wait, because the run() method is already finished.
One of the possible solutions could be:
1. create a new flag variable in ListenerThread
2. the run method will set this flag to true
3. the waitUntilRun() method will keep calling this.wait() while this flag is not set
I will attach a diff patch soon.
Patch attached. I would like to ask for a review.
Best wishes,
Jozef
Infinite wait in ListenerThread.waitUntilRun
Hi Jozef,
We'll check your patch. I understand your problem. We are using GXNet in some critical reading systems and we have to think this very carefully so we don't break anything.
BR,
Mikko
Sure, take your time :).
I have attached an improved patch. It synchronizes and waits on the local AtomicBoolean variable instead of the class instance. It *should* in theory give a slightly better performance. Also the notifyAll() was replaced by notify() since there is usually one thread waiting at most.
Jozef
I would like to ask: is there
I would like to ask: is there anything new on this issue?
Thank you for Your response.
Jozef
Infinite wait in ListenerThread.waitUntilRun
Hi,
We are releasing new version today or latest on Monday.
BR,
Mikko
Infinite wait in ListenerThread.waitUntilRun
Hi,
We have released 1.0.15 on Friday. Please, let me know if you still have problems.
BR,
Mikko
all good!
Thank You for the fix, it works great with the new libraries.
Jozef