这是我的情景。
我有一个频率池,我的BaseStation
需要选择其中一个。 BaseStation
的关键部分是进入频率选择的阶段。一旦选择频率,控制将返回主BaseStation
类,并恢复其请求生成。同时,即一旦它退出其临界区,所选择的频率将进入使用状态一段时间,这将由随机时钟决定。因此,此频率将无法用于过渡期间发生的任何其他请求。一旦频率使用时间结束,它只是将其状态再次设置为可用。因此,BaseStation
的互斥部分仅用于频率选择,一旦结束,BaseStation
功能和频率使用时间并行运行。
到目前为止我的编码方式是:我有三个课程BaseStation
,CriticalSection
和UseFrequency
。 BaseStation
调用CriticalSection
中的函数进行频率选择,一旦频率被选中,我就有一个函数在另一个类中启动一个线程以供频率使用,然后很快将控制权返回到BaseStation
:
UseFrequency freqInUse = new UseFrequency;
freqInUse.start();
return 1;
但是一旦线程停止,类CriticalSection
需要更新一些变量,我很困惑如何将控制权返回给中产阶级。我需要使用两个线程吗?
答案 0 :(得分:4)
我不确定你的问题是什么(所以我猜对了!)但是有一个选择是将Apache GenericObjectPool
包装起来存储你的Frequency
个对象并调用{{1从池中删除borrowObject()
并指示它“正在使用中”。在调用Frequency
之后,您还可以安排任务(例如,使用borrowObject()
)在将来的某个时刻调用ScheduledExecutorService
,从而使returnObject()
再次可用于其他线程
Frequency
答案 1 :(得分:2)
控制此类事件的并发性的最简单方法可能是ReadWriteLock(ReentrantReadWriteLock是实现)。在进行频率选择时,您应该锁定写锁定,然后在完成时解锁。正常使用只会获得读锁。这在频率选择期间提供互斥,但在其他情况下同时使用。
可以使用Semaphore构建更通用的解决方案,对一组池化资源进行更细粒度的控制。
答案 2 :(得分:1)
保留一组频率,以及频率状态的另一个数组,无论是使用还是未使用。您需要一个读写锁来访问频率。一旦开始使用频率,就可以将频率的状态设置为使用,启动定时器,该定时器触发获取写锁定的改变,并将频率状态改变回未使用状态。
答案 3 :(得分:0)
现在我明白了这个问题。使用可观察的模式将是一个很好的方法。这是我喜欢Javaworld的一个例子:http://www.javaworld.com/javaworld/javatips/jw-javatip29.html
答案 4 :(得分:0)
为了将控制权返回给调用临界区,使用Executor来执行你的线程.Eg:
块引用 ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> future = executor.submit(//submit frequency thread runnable object);
try {
future.get();
//do critical section update
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
executor.shutdown();