Threadpool problem
Anyone ever use a Threadpool in Duet? I am getting IOExceptions when the threadpool starts reusing threads to execute tasks greater than the number of threads in the pool.
The tasks run but I get that exception for each execution greater than the number of threads. Here is the actual code I am using:
Anyone have any ideas?
(0000050263) Morpheus: Starting devicesdkrt.jar (0000056025) Morpheus: Starting snapirouter.jar (0000071844) Task 1 Started @ Mon Apr 07 09:05:17 GMT 2014 (0000071850) Task 2 Started @ Mon Apr 07 09:05:17 GMT 2014 (0000071855) Task 3 Started @ Mon Apr 07 09:05:17 GMT 2014 (0000071859) Task 4 Started @ Mon Apr 07 09:05:17 GMT 2014 (0000071864) Task 5 Started @ Mon Apr 07 09:05:17 GMT 2014 (0000071868) Task 6 Started @ Mon Apr 07 09:05:17 GMT 2014 (0000071872) Task 7 Started @ Mon Apr 07 09:05:17 GMT 2014 (0000071876) Task 8 Started @ Mon Apr 07 09:05:17 GMT 2014 (0000071881) Task 9 Started @ Mon Apr 07 09:05:17 GMT 2014 (0000071885) Task 10 Started @ Mon Apr 07 09:05:17 GMT 2014 (0000073085) SNAPIRouter: UtilityComponent loaded (0000073205) SNAPIRouter: ModuleComponent loaded (0000073363) Task 1 Complete @ Mon Apr 07 09:05:19 GMT 2014 (0000073366) Task 2 Complete @ Mon Apr 07 09:05:19 GMT 2014 (0000073369) Task 3 Complete @ Mon Apr 07 09:05:19 GMT 2014 (0000073372) Task 4 Complete @ Mon Apr 07 09:05:19 GMT 2014 (0000073376) Task 5 Complete @ Mon Apr 07 09:05:19 GMT 2014 (0000073379) Task 6 Complete @ Mon Apr 07 09:05:19 GMT 2014 (0000073382) Task 7 Complete @ Mon Apr 07 09:05:19 GMT 2014 (0000073385) Task 8 Complete @ Mon Apr 07 09:05:19 GMT 2014 (0000073388) Task 9 Complete @ Mon Apr 07 09:05:19 GMT 2014 (0000073391) Task 10 Complete @ Mon Apr 07 09:05:19 GMT 2014 (0000073412) Task 11 Started @ Mon Apr 07 09:05:19 GMT 2014 (0000073426) java.io.IOException (0000073430) at sun.misc.Unsafe.compareAndSwapObject (Native Method) (0000073432) at java.util.concurrent.locks.AbstractQueuedSynchronizer.compare AndSetHead (Unknown Source, bco=9) (0000073434) at java.util.concurrent.locks.AbstractQueuedSynchronizer.enq (Un known Source, bco=32) (0000073436) at java.util.concurrent.locks.AbstractQueuedSynchronizer.addWait er (Unknown Source, bco=47) (0000073438) at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcqui reInterruptibly (Unknown Source, bco=7) (0000073440) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire Interruptibly (Unknown Source, bco=27) (0000073443) at java.util.concurrent.locks.ReentrantLock.lockInterruptibly (U nknown Source, bco=8) (0000073451) at java.util.concurrent.LinkedBlockingQueue.take (Unknown Source , bco=18) (0000073458) at java.util.concurrent.ThreadPoolExecutor.getTask (Unknown Sour ce, bco=52) (0000073536) at java.util.concurrent.ThreadPoolExecutor$Worker.run (Unknown S ource, bco=21) (0000073537) at java.lang.Thread.run (Unknown Source, bco=16)
The tasks run but I get that exception for each execution greater than the number of threads. Here is the actual code I am using:
package com.ctsi_usa.duet.virtual.thread.dr1_0_0;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.osgi.framework.BundleContext;
import com.amx.duet.da.NetLinxDevice;
import com.amx.duet.devicesdk.Utility;
public class VirtualThread extends Utility{
private static final int POOL_SIZE = 10;
private ExecutorService threadPool = Executors.newFixedThreadPool(POOL_SIZE);;
private List futureList = new ArrayList();
/**
*
*/
public VirtualThread() {
super();
}
/**
* @param bctxt
* @param nd
* @param props
*/
public VirtualThread(BundleContext bctxt, NetLinxDevice nd, Properties props) {
super(bctxt, nd, props);
Thread m = new Thread(new Runnable(){
public void run() {
doThreadPool();
}
});
m.start();
}
/* (non-Javadoc)
* @see com.amx.duet.devicesdk.base.Module#doAddNetLinxDeviceListeners()
*/
protected void doAddNetLinxDeviceListeners() {
}
/* (non-Javadoc)
* @see com.amx.duet.devicesdk.base.Module#doNetLinxDeviceInitialization()
*/
protected boolean doNetLinxDeviceInitialization() {
return false;
}
/* (non-Javadoc)
* @see com.amx.duet.devicesdk.base.Module#isDeviceOnLine()
*/
public boolean isDeviceOnLine() {
return false;
}
/* (non-Javadoc)
* @see com.amx.duet.devicesdk.base.Module#isDataInitialized()
*/
public boolean isDataInitialized() {
return false;
}
private void doThreadPool() {
for (int x = 1; x < 31; x++) {
try {
futureList.add(threadPool.submit(new TestRunnable("Task " + x)));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
And TestRunnable Class:
package com.ctsi_usa.duet.virtual.thread.dr1_0_0;
import java.util.Date;
public class TestRunnable implements Runnable {
private String name;
/**
*
*/
public TestRunnable(String name) {
super();
this.name = name;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
public void run() {
System.out.println(name + " Started @ " + new Date());
try {
Thread.sleep(1500);
System.out.println(name + " Complete @ " + new Date());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Anyone have any ideas?
0
Comments
I don't think your code can cause the problem, it seems that something goes wrong in a lower level: if you run this snippet on a "real" JVM, do you get any error?
package threadpooltest; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolTest { /** * @param args the command line arguments */ public static void main(String[] args) { final ExecutorService threadPool = Executors.newFixedThreadPool(10); Thread m = new Thread(new Runnable() { @Override public void run() { doThreadPool(threadPool); } }); m.start(); } private static void doThreadPool(ExecutorService eService) { for (int x = 1; x < 31; x++) { try { eService.submit(new TestRunnable("Task " + x)); } catch (Exception e) { e.printStackTrace(); } } } }TestRunnable class.package threadpooltest; import java.util.Date; public class TestRunnable implements Runnable { private final String name; public TestRunnable(String name) { this.name = name; } @Override public void run() { System.out.println(name + " Started @ " + new Date()); try { Thread.sleep(1500); System.out.println(name + " Complete @ " + new Date()); } catch (InterruptedException e) { e.printStackTrace(); } }Output: What I have found from research online it seems like the ReentrantLock class throws that Exception when a Thread tries to release a lock it does not own. I have submitted this to AMX but it will take awhile to hear back form the Duet guys that we mere mortals are not allowed to interact with directly. I imagine that there response will be something like "the code still runs what are you complaining about?"when you try to unlock a monitor you don't own, an IllegalMonitorStateException is thrown, but in you case we have an IOException from the Unsafe class... that's why I feel there's something wrong somewhere down into hidden system layers
Good luck :-P