Concurrency
JasonS
If I had known it was going to be that kind of party...
Anyone have a good way to transfer execution from a Timer's Thread back to the Thread that called it when times up?
Comments
-
Which Timer are we talking about here, the one from java.util or the SDK one?
If you are just looking to link something to the tail of another thread Thread.join() is what you are after. This will pause the thread that it is called from until the thread you are joining completes. -
I'm using the AMX one out of laziness. It is being called from a thread that is handling IP communication. I need the thread to pause until it is closer to the increment of a minute so that it can update time on a device that doesn't accept seconds. Currently this code runs in the timers thread so the offset across multiple threads becomes progressively greater. Can join be used with the AMX Timer? Doesn't it's thread keep running since all Timers use the same thread?
I was trying to use a CountDownLatch, but it is throwing an IOException when it encounters the await().package com.ctsi_usa.duet.virtual.test.dr1_0_0; import java.util.Properties; import java.util.concurrent.CountDownLatch; import org.osgi.framework.BundleContext; import com.amx.duet.da.NetLinxDevice; import com.amx.duet.devicesdk.Utility; import com.amx.duet.util.Timer; import com.amx.duet.util.TimerListener; public class VirtualTest extends Utility{ Timer timer1 = null; Timer timer2 = null; final CountDownLatch cdl = new CountDownLatch(1); TimerListener timerHandler = new InnerTimerHandler(cdl); public VirtualTest() { super(); } /** * @param bctxt * @param nd * @param props */ public VirtualTest(BundleContext bctxt, NetLinxDevice nd, Properties props) { super(bctxt, nd, props); timer1 = new Timer(timerHandler, 5000); System.out.println("timer1 started"); Thread.currentThread().setName("VirtualTest main Thread"); timer1.start(); new Thread(new InnerRunnable(cdl)).start(); } private class InnerTimerHandler implements TimerListener { CountDownLatch latch; public InnerTimerHandler(CountDownLatch latch) { this.latch = latch; } /* (non-Javadoc) * @see com.amx.duet.util.TimerListener#handleTimerEvent(com.amx.duet.util.Timer) */ public void handleTimerEvent(Timer arg0) { if (arg0.equals(timer1)) { System.out.println("timer1 code ran in " + Thread.currentThread().getName()); } else if (arg0.equals(timer2)) { System.out.println("timer2 cdl.countDown() running in " + Thread.currentThread().getName()); latch.countDown(); } } } private class InnerRunnable implements Runnable { CountDownLatch latch; public InnerRunnable(CountDownLatch latch) { this.latch = latch; } /* (non-Javadoc) * @see java.lang.Runnable#run() */ public void run() { System.out.println("InnerRunnable Thread Started"); Thread.currentThread().setName("InnerRunnable Thread"); //cdl = new CountDownLatch(1); timer2 = new Timer(timerHandler, 8000); timer2.start(); System.out.println("timer2 started"); try { latch.await(); System.out.println("code after cdl.await() running in " + Thread.currentThread().getName()); } catch (Exception e) { System.out.println("cdl.await() Exception"); e.printStackTrace(); } } } }This code requires Master Firmware 4.x.x Java Libraries
This is the Output:
(0000051591) Framework launched
(0000052248) Creating Thread Pool
(0000052415) AmxSslServerSocket(int,int): got called
(0000055100) Device Access: No DriverLocators found
(0000056433) Morpheus: Starting devicesdkrt.jar
(0000062868) Morpheus: Starting snapirouter.jar
(0000078798) timer1 started
(0000078824) InnerRunnable Thread Started
(0000078826) timer2 started
(0000078828) cdl.await() Exception
(0000078829) java.io.IOException
(0000078833) at sun.misc.Unsafe.compareAndSwapObject (Native Method)
(0000078835) at java.util.concurrent.locks.AbstractQueuedSynchronizer.compare
AndSetHead (Unknown Source, bco=9)
(0000078837) at java.util.concurrent.locks.AbstractQueuedSynchronizer.enq (Un
known Source, bco=32)
(0000078838) at java.util.concurrent.locks.AbstractQueuedSynchronizer.addWait
er (Unknown Source, bco=47)
(0000078839) at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcqui
reSharedInterruptibly (Unknown Source, bco=7)
(0000078841) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire
SharedInterruptibly (Unknown Source, bco=27)
(0000078892) at java.util.concurrent.CountDownLatch.await (Unknown Source, bc
o=8)
(0000078894) at com.ctsi_usa.duet.virtual.test.dr1_0_0.VirtualTest$InnerRunna
ble.run (VirtualTest.java:123)
(0000078895) at java.lang.Thread.run (Unknown Source, bco=16)
(0000080081) SNAPIRouter: UtilityComponent loaded
(0000080207) SNAPIRouter: ModuleComponent loaded
(0000083815) timer1 code ran in TimerDaemon
(0000086829) timer2 cdl.countDown() running in TimerDaemon -
Found a solution, it doesn't even require the new libraries. I'm kind of disappointed.
public class SyncObject { public SyncObject() { super(); } public void doWait() throws InterruptedException { synchronized(this) { this.wait(); } } public void doNotify() { synchronized(this) { this.notify(); } } }import com.amx.duet.util.Timer; import com.amx.duet.util.TimerListener; public class SyncTimer { private SyncObject sync; private Timer timer; private InnerHandler handler = this.new InnerHandler(); public SyncTimer(long time, SyncObject sync) { super(); timer = new Timer(handler, time); this.sync = sync; } public void start() { timer.start(); } private class InnerHandler implements TimerListener { public void handleTimerEvent(Timer arg0) { if (arg0.equals(timer) && sync != null) { System.out.println("SyncTimer timed out in " + Thread.currentThread().getName()); sync.doNotify(); } } } }import java.util.Properties; import org.osgi.framework.BundleContext; import com.amx.duet.da.NetLinxDevice; import com.amx.duet.devicesdk.Utility; import com.amx.duet.util.Timer; import com.amx.duet.util.TimerListener; public class VirtualTest extends Utility{ SyncTimer timer2; SyncObject sync; public VirtualTest() { super(); } /** * @param bctxt * @param nd * @param props */ public VirtualTest(BundleContext bctxt, NetLinxDevice nd, Properties props) { super(bctxt, nd, props); Thread.currentThread().setName("VirtualTest main Thread"); new Thread(this.new InnerRunnable()).start(); } private class InnerRunnable implements Runnable { public void run() { System.out.println("InnerRunnable Thread Started"); Thread.currentThread().setName("InnerRunnable Thread"); sync = new SyncObject(); timer2 = new SyncTimer(8000, sync); timer2.start(); try { sync.doWait(); System.out.println("code after sync.doWait() running in " + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } } }
Output:
(0000046272) Framework launched
(0000046929) Creating Thread Pool
(0000047141) AmxSslServerSocket(int,int): got called
(0000049256) Device Access: No DriverLocators found
(0000050594) Morpheus: Starting devicesdkrt.jar
(0000055953) Morpheus: Starting snapirouter.jar
(0000072411) InnerRunnable Thread Started
(0000073642) SNAPIRouter: UtilityComponent loaded
(0000073761) SNAPIRouter: ModuleComponent loaded
(0000080500) SyncTimer timed out in TimerDaemon
(0000080502) code after sync.doWait() running in InnerRunnable Thread
Categories
- All Categories
- 2.5K AMX General Discussion
- 922 AMX Technical Discussion
- 514 AMX Hardware
- 502 AMX Control Products
- 3 AMX Video Distribution Products
- 9 AMX Networked AV (SVSI) Products
- AMX Workspace & Collaboration Products
- 3.4K AMX Software
- 151 AMX Resource Management Suite Software
- 386 AMX Design Tools
- 2.4K NetLinx Studio
- 135 Duet/Cafe Duet
- 248 NetLinx Modules & Duet Modules
- 57 AMX RPM Forum
- 228 MODPEDIA - The Public Repository of Modules for Everyone
- 943 AMX Specialty Forums
- 2.6K AMXForums Archive
- 2.6K AMXForums Archive Threads
- 1.5K AMX Hardware
- 432 AMX Applications and Solutions
- 249 Residential Forum
- 182 Tips and Tricks
- 146 AMX Website/Forums